<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="keywords" content="jujuul">
<meta name="description" content="温故而知新">
<meta name="theme-color" content="#000">
<title>Mark</title>
<link rel="shortcut icon" href="/favicon.ico?v=1600868123037">
<link rel="stylesheet" href="/media/css/mist.css">
<link rel="stylesheet" href="/media/fonts/font-awesome.css">
<link
  href="//fonts.googleapis.com/css?family=Monda:300,300italic,400,400italic,700,700italic|Roboto Slab:300,300italic,400,400italic,700,700italic|Rosario:300,300italic,400,400italic,700,700italic|PT Mono:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext"
  rel="stylesheet" type="text/css">

<link href="/media/hljs/styles/default.css"
  rel="stylesheet">

<link rel="stylesheet" href="/styles/main.css">

<script src="/media/hljs/highlight.js"></script>
<script src="https://cdn.jsdelivr.net/npm/velocity-animate@1.5.0/velocity.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/velocity-animate@1.5.0/velocity.ui.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css"
  integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous">


<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js"
  integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/auto-render.min.js"
  integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous"
  onload="renderMathInElement(document.body);"></script>





</head>

<body>
  <div class="head-top-line"></div>
  <div class="header-box">
    
<div class="mist">
  <header class="header bg-color ">
    <div class="blog-header box-shadow-wrapper  " id="header">
      <div class="nav-toggle" id="nav_toggle">
        <div class="toggle-box">
          <div class="line line-top"></div>
          <div class="line line-center"></div>
          <div class="line line-bottom"></div>
        </div>
      </div>
      <div class="site-meta">       
        <div class="site-title">
          
            <a href="/" class="">
              <span class="logo-line-before">
                <i class=""></i>
              </span>
              <span class="main-title">Mark</span>
              <span class="logo-line-after">
                <i class=""></i>
              </span>
            </a>  
          
        </div>
        
      </div>
      <nav class="site-nav" id="site_nav">
        <ul id="nav_ul">
          
            
            
              
            
            <li class="nav-item ">
              
              
                <a href="learn/" target="_self">
                  <i class="fa fa-globe"></i> 测试
                </a>
              
            </li>
          
          
            
              <li class="nav-item ">
                <a href="/friends/" target="_self">
                  
                    <i class="fa fa-address-book"></i> 友情链接
                  
                </a>
              </li>
            
          
          
            <li id="fa_search" class="nav-item">
              <a href="javascript:void(0);">
                <i class="fa fa-search"></i> <span class="language" data-lan="search">搜索</span>
              </a>
            </li>
          
        </ul>
      </nav>
    </div>
  </header>
</div>

<script type="text/javascript"> 
 
  let showNav = true;

  let navToggle = document.querySelector('#nav_toggle'),
  siteNav = document.querySelector('#site_nav');
  
  function navClick() {
    let sideBar = document.querySelector('.sidebar');
    let navUl = document.querySelector('#nav_ul');
    navToggle.classList.toggle('nav-toggle-active');
    siteNav.classList.toggle('nav-menu-active');
    if (siteNav.classList.contains('nav-menu-active')) {
      siteNav.style = "height: " + (navUl.children.length * 42) +"px !important";
    } else {
      siteNav.style = "";
    }
  }

  navToggle.addEventListener('click',navClick);  
</script>
  </div>
  <div class="main-continer">
    
    <div
      class="section-layout mist bg-color">
      <div class="section-layout-wrapper">
        <div id="sidebarMeta" class="sidebar">
    
<div class="sidebar-wrapper box-shadow-wrapper ">
  <div class="sidebar-item">
    <img class="site-author-image right-motion" src="/images/avatar.png"/>
    <p class="site-author-name">适用 Gemini,Pisces 布局,版权说明需配置</p>
    
  </div>
  <div class="sidebar-item side-item-stat right-motion">
    <div class="sidebar-item-box">
      <a href="/archives/">
        
        <span class="site-item-stat-count">66</span>
        <span class="site-item-stat-name language" data-lan="article">文章</span>
      </a>
    </div>
    <div class="sidebar-item-box">
      <a href="">
        <span class="site-item-stat-count">3</span>
        <span class="site-item-stat-name language" data-lan="category">分类</span>
      </a>
    </div>
    <div class="sidebar-item-box">
      <a href="/tags/">
        <span class="site-item-stat-count">3</span>
        <span class="site-item-stat-name language" data-lan="tag">标签</span>
      </a>
    </div>
  </div>
  
  



</div>
</div>
<script>
  let sidebarMeta = document.querySelector('#sidebarMeta');
  let scheme = 'mist';
  let sidebarWrapper = document.querySelector('.sidebar-wrapper');
  if (sidebarMeta && (scheme === 'pisces' || scheme === 'gemini')) {
    document.addEventListener('scroll', function(e) {
      if (document.scrollingElement.scrollTop > parseInt(sidebarMeta.style.marginTop) + 10) {
        sidebarWrapper.classList.add('home-sidebar-fixed')
      } else {
        sidebarWrapper.classList.remove('home-sidebar-fixed')
      }
    });
  }
  </script>
        <div class="section-box mist">
          <section class="section bg-color posts-expand slide-down-in">
            
  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/bai-du-sou-suo-ye-geng-xin-liao/">
      百度搜索页更新了
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-11 18:11:34">2020-09-11</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>1<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>231<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
              
            
              
              
              
            
            
              <p><p>今天打开百度搜索一点东西，发现搜索结果页变了，变得更加“圆润”、“圆滑”了，字体改变了，下面的分页标签也改了，变成了圆角矩形<img src="https://jujuul.github.io//post-images/1599819940269.PNG" alt="" loading="lazy"><br>
页面上文字颜色也改变了，变得更淡了，页面上加载的图片也全都变成圆角矩形了<br>
<img src="https://jujuul.github.io//post-images/1599819914261.PNG" alt="" loading="lazy"><br>

                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/bai-du-sou-suo-ye-geng-xin-liao/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>

  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-hippy/">
      每天一个名词解释—Hippy
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-10 12:19:33">2020-09-10</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>3<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>628<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
              
            
              
              
              
            
            
              <p><h2 id="前言">前言：</h2>
<p>记得之前看过几篇前端跨端框架的文章，里面提到最多的就是uniapp、taro、mpvue，而截至目前，最为主流的应该就是uniapp和taro了，因为使用vue的关系，所以uniapp我也稍微看过，当时就在想，为什么有京东和美团的，不见阿里腾讯的呢？今天码云推送的一篇文章终于提到了，Hippy—腾讯的跨端开发框架。</p>
<h2 id="介绍">介绍：</h2>

                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-hippy/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>

  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/vuex-shu-ju-chi-jiu-hua-cha-jian/">
      vuex 数据持久化插件
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-09 12:25:51">2020-09-09</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>2<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>246<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
              
            
              
              
              
            
            
              <p><ol>
<li>安装<br>
<code>npm install vuex-persistedstate</code></li>

                
                  <!-- 自动摘要出来的内容有<code则补上结尾,防止格式错误 -->
                  </code></pre>
                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/vuex-shu-ju-chi-jiu-hua-cha-jian/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>

  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/zhuan-zai-na-xie-ni-zong-shi-ji-bu-zhu-dan-you-zong-shi-yao-yong-de-css/">
      转载：那些你总是记不住但又总是要用的css
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-09 10:46:34">2020-09-09</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>2<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>381<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
              
            
              
              
              
            
            
              <p><h2 id="一-设置input-的placeholder的字体样式">一、设置input 的placeholder的字体样式</h2>
<pre><code>input::-webkit-input-placeholder {    /* Chrome/Opera/Safari */
    color: red;

                
                  <!-- 自动摘要出来的内容有<code则补上结尾,防止格式错误 -->
                  </code></pre>
                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/zhuan-zai-na-xie-ni-zong-shi-ji-bu-zhu-dan-you-zong-shi-yao-yong-de-css/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>

  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/vuex-yu-dao-de-yi-ge-cuo-wu/">
      vuex遇到的一个错误
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-08 21:09:41">2020-09-08</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>1<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>133<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
              
            
              
              
              
            
            
              <p><p>使用vuex的mutations时遇到的一个错误，找了一下没找到答案，换个方法就规避了这个错误，这个应该不算是错误，因为报错提示<code>handler: &quot;Error: [vuex] expects string as the type, but found undefined.&quot;</code>是需要字符串，我这边传递的是对象，之前的使用中也是传递的字符串，所以错误应该是这个原因。<br>
错误代码</p>
<pre><code>...mapMutations({

                
                  <!-- 自动摘要出来的内容有<code则补上结尾,防止格式错误 -->
                  </code></pre>
                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/vuex-yu-dao-de-yi-ge-cuo-wu/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>

  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-amis/">
      每天一个名词解释—amis
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-07 14:40:59">2020-09-07</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>5<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>1214<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
              
            
              
              
              
            
            
              <p><h2 id="什么是-amis">什么是 amis</h2>
<p>amis 是一个低代码前端框架，它使用 JSON 配置来生成页面，可以减少页面开发工作量，极大提升效率。</p>
<h2 id="为什么要做-amis">为什么要做 amis？</h2>

                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-amis/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>

  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/b-zhan-bo-fang-qi-de-yi-ge-xiao-bug/">
      B站播放器的一个小BUG
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-06 23:25:25">2020-09-06</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>1<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>142<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
            
              <p><p>其实这个bug已经有好几天了，但是迟迟没修让我不禁怀疑是不是只有我遇到了这个bug，前几天的时候是打开新视频，当音量大于50%的时候，不论怎么调节，只要不使音量&lt;=50%都不显示音量图标，静音的情况没有测试，今晚使用发现当音量&lt; 50%的时候，会出现跟之前上面一样的情况(切换到静音状态再调节就好了)，不知道是不是修了旧bug又有了新bug。</p>

                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/b-zhan-bo-fang-qi-de-yi-ge-xiao-bug/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>

  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/bo-fang-qi-jin-du-tiao-gai-jin/">
      播放器进度条改进
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-05 16:16:30">2020-09-05</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>3<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>517<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
              
            
              
              
              
            
            
              <p><p>因为不满意之前的进度条样式，所以决定更换进度条，在参考多个其他项目之后，我发现还是elementUI的进度条比较合适，所以就换成了elementUI的slider组件，因为组件默认的颜色是蓝色，所以这里使用样式穿透更改组件颜色以及组件的高度，宽度等显示效果。</p>
<pre><code>.slider /deep/ .el-slider {
  margin: 2px 4px;

                
                  <!-- 自动摘要出来的内容有<code则补上结尾,防止格式错误 -->
                  </code></pre>
                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/bo-fang-qi-jin-du-tiao-gai-jin/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>

  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/uniapp-sheng-tai-xia-de-ui-kuang-jia-uview/">
      uniapp生态下的UI框架—uView
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-04 14:56:59">2020-09-04</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>3<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>621<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
              
            
              
              
              
            
            
              <p><p>项目名称：uView项目作者：亡灵叙曲开源许可协议：MIT项目地址：https://gitee.com/xuqu/uView项目简介uView UI，是 uni-app 生态优秀的UI框架，全面的组件和便捷的工具会让您信手拈来，如鱼得水。项目特性兼容安卓，iOS，微信小程序，H5，QQ小程序，百度小程序，支付宝小程序，头条小程序60+精选组件，功能丰富，多端兼容，让您快速集成，开箱即用众多贴心的JS利器，让您飞镖在手，召之即来，百步穿杨众多的常用页面和布局，让您专注逻辑，事半功倍详尽的文档支持，现代化的演示效果按需引入，精简打包体积</p>
<h2 id="项目截图">项目截图</h2>
<p><img src="https://jujuul.github.io//post-images/1599202752683.jpg" alt="" loading="lazy"><br>

                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/uniapp-sheng-tai-xia-de-ui-kuang-jia-uview/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>

  <article class="post-list-box  post box-shadow-wrapper">
    <div class="article-wrapper bg-color">
      <section class="post-header">
  <h1 class="post-title">
    <a class="post-title-link" href="https://jujuul.github.io/post/sou-suo-zu-jian/">
      搜索组件
    </a>
  </h1>
  <div class="post-meta">
    
    <span class="meta-item pc-show">
      <i class="fa fa-calendar-o"></i>
      <span class="language" data-lan="publish">发布于</span>
      <span class="publish-time" data-t="2020-09-02 16:45:32">2020-09-02</span>
      <span class="post-meta-divider pc-show">|</span>
    </span>
    
    <span class="meta-item">
      <i class="fa fa-clock-o"></i>
      <span>3<span class="language" data-lan="minute">分钟</span></span>
    </span>
    <span class="meta-item">
      <span class="post-meta-divider">|</span>
      <i class="fa fa-file-word-o"></i>
      <span>683<span class="pc-show language" data-lan="words">字数</span></span>
    </span>
    
  </div>
</section>
      <div class="post-body">
        
        
          
            <!-- 没有手动摘要切开启了自动摘要,则根据配置筛除摘要内容 -->
            
            
              
              
              
            
              
              
              
            
              
              
              
            
            
              <p><p>做到了搜索功能，因为之前没做过，在这里卡了一下，所以记录一下。<br>
一开始是打算做成网易云的样式的，就是input聚焦以后弹出弹出层，然后里面列出推荐关键词，如果有历史搜索记录也列出来，但是这样效果很平常，所以就换了一个样式，换成点击搜索图标，整个页面模糊，弹出层内显示一个搜索框，下面列出推荐关键词。<br>
先是实现背景模糊</p>

                
              <p>
            
          
        
        
        <div class="post-button text-center">
          <a class="btn language" data-lan="read-more" href="https://jujuul.github.io/post/sou-suo-zu-jian/" rel="contents">
            阅读全文 »
          </a>
        </div>
        
      </div>
      
        <footer class="post-footer">
          <div class="post-eof"></div>
        </footer>
      
    </div>
  </article>
  
            
            
<div class="page bg-color">
  <ul class="pagination-ul">
    
      <li class="pagination-dir">
        <a href="https://jujuul.github.io/">
          <i class="fa fa-angle-left"></i>
        </a>
      </li>
    
    
      <!-- 1 2 3 4 ... N -->
      
        
          
            <li class="pagination-li ">
              <a href="/">1</a>
            </li>
          
        
          
            <li class="pagination-li pagination-active">
              <a href="/page/2">
                2
              </a>
            </li>
          
        
          
            <li class="pagination-li ">
              <a href="/page/3">
                3
              </a>
            </li>
          
        
          
            <li class="pagination-li ">
              <a href="/page/4">
                4
              </a>
            </li>
          
        
        <li class="pagination-li">
          …
        </li>
        <li class="pagination-li">
          <a href="/page/7">
            7
          </a>
        </li>
      
    
    
      <li class="pagination-dir">
        <a href="/page/3">
          <i class="fa fa-angle-right"></i>
        </a>
      </li>
    
  </ul>
</div>
          </section>
        </div>
      </div>
    </div>
    <div class="footer-box">
  <footer class="footer">
    <div class="copyright">
      Powered by <a href="https://github.com/getgridea/gridea" target="_blank">Gridea</a> | © 2019-2020 Theme By <a
        href="https://github.com/hsxyhao/gridea-theme-next" target="_blank">HsxyHao</a>
    </div>
    <div class="poweredby">
      Powered by <a href="https://github.com/getgridea/gridea" target="_blank">Gridea</a>
    </div>
  </footer>
  
  
  <div class="drawer-box left" id="drawer_box">
    <span class="muse-line muse-line-first"></span>
    <span class="muse-line muse-line-middle"></span>
    <span class="muse-line muse-line-last"></span>
  </div>
  
  <div class="mist back-to-top" id="back_to_top">
    <i class="fa fa-arrow-up"></i>
    
  </div>
  
  
  
</div>
<script>

  let sideBarOpen = 'sidebar-open';
  let body = document.body;
  let back2Top = document.querySelector('#back_to_top'),
    back2TopText = document.querySelector('#back_to_top_text'),
    drawerBox = document.querySelector('#drawer_box'),
    rightSideBar = document.querySelector('.sidebar'),
    viewport = document.querySelector('body');

  function scrollAnimation(currentY, targetY) {

    let needScrollTop = targetY - currentY
    let _currentY = currentY
    setTimeout(() => {
      const dist = Math.ceil(needScrollTop / 10)
      _currentY += dist
      window.scrollTo(_currentY, currentY)
      if (needScrollTop > 10 || needScrollTop < -10) {
        scrollAnimation(_currentY, targetY)
      } else {
        window.scrollTo(_currentY, targetY)
      }
    }, 1)
  }

  back2Top.addEventListener("click", function (e) {
    scrollAnimation(document.scrollingElement.scrollTop, 0);
    e.stopPropagation();
    return false;
  });

  window.addEventListener('scroll', function (e) {
    let percent = document.scrollingElement.scrollTop / (document.scrollingElement.scrollHeight - document.scrollingElement.clientHeight) * 100;
    if (percent > 1 && !back2Top.classList.contains('back-top-active')) {
      back2Top.classList.add('back-top-active');
    }
    if (percent == 0) {
      back2Top.classList.remove('back-top-active');
    }
    if (back2TopText) {
      back2TopText.textContent = Math.floor(percent);
    }
  });


  let hasCacu = false;
  window.onresize = function () {
    calcuHeight();
  }

  function calcuHeight() {
    // 动态调整站点概览高度
    if (!hasCacu && back2Top.classList.contains('pisces') || back2Top.classList.contains('gemini')) {
      let sideBar = document.querySelector('.sidebar');
      let navUl = document.querySelector('#site_nav');
      sideBar.style = 'margin-top:' + (navUl.offsetHeight + navUl.offsetTop + 15) + 'px;';
      hasCacu = true;
    }
  }
  calcuHeight();

  let open = false, MOTION_TIME = 300, RIGHT_MOVE_DIS = '320px';

  if (drawerBox) {
    let rightMotions = document.querySelectorAll('.right-motion');
    let right = drawerBox.classList.contains('right');

    let transitionDir = right ? "transition.slideRightIn" : "transition.slideLeftIn";

    let openProp, closeProp;
    if (right) {
      openProp = {
        paddingRight: RIGHT_MOVE_DIS
      };
      closeProp = {
        paddingRight: '0px'
      };
    } else {
      openProp = {
        paddingLeft: RIGHT_MOVE_DIS
      };
      closeProp = {
        paddingLeft: '0px'
      };
    }

    drawerBox.onclick = function () {
      open = !open;
      window.Velocity(rightSideBar, 'stop');
      window.Velocity(viewport, 'stop');
      window.Velocity(rightMotions, 'stop');
      if (open) {
        window.Velocity(rightSideBar, {
          width: RIGHT_MOVE_DIS
        }, {
          duration: MOTION_TIME,
          begin: function () {
            window.Velocity(rightMotions, transitionDir, {});
          }
        })
        window.Velocity(viewport, openProp, {
          duration: MOTION_TIME
        });
      } else {
        window.Velocity(rightSideBar, {
          width: '0px'
        }, {
          duration: MOTION_TIME,
          begin: function () {
            window.Velocity(rightMotions, {
              opacity: 0
            });
          }
        })
        window.Velocity(viewport, closeProp, {
          duration: MOTION_TIME
        });
      }
      for (let i = 0; i < drawerBox.children.length; i++) {
        drawerBox.children[i].classList.toggle('muse-line');
      }
      drawerBox.classList.toggle(sideBarOpen);
    }
  }

  // 链接跳转
  let newWindow = 'false'
  if (newWindow === 'true') {
    let links = document.querySelectorAll('.post-body a')
    links.forEach(item => {
      if (!item.classList.contains('btn')) {
        item.setAttribute("target", "_blank");
      }
    })
  }

  let faSearch = document.querySelector('#fa_search');
  faSearch.addEventListener('click', function () {
    document.querySelector('#search_mask').style = ''
  })

  // 代码高亮
  hljs.initHighlightingOnLoad();
  
  // 离开当前页title变化
  var leaveTitle = "";
  if (leaveTitle) {
    document.addEventListener('visibilitychange', function () {
      if (document.visibilityState == 'hidden') {
        normal_title = document.title;
        document.title = leaveTitle;
      } else {
        document.title = normal_title;
      }
    });
  }

</script>
    <div class="light-box" id="light_box"></div>
<script>
  let imgs = document.querySelectorAll('.post-body img');
  let lightBox = document.querySelector('#light_box');
  lightBox.addEventListener('mousedown', (e) => {
    e.preventDefault()
  })
  lightBox.addEventListener('mousewheel', (e) => {
    e.preventDefault()
  })
  let width = window.innerWidth * 0.8;
  lightBox.onclick = () => {
    let img = lightBox.querySelector('img');
    lightBox.style = '';
    img && img.remove();
  }
  imgs.forEach(item => {
    item.onclick = function (e) {
      let lightImg = document.createElement('img');
      lightImg.src = this.src;
      lightBox.style = `height: 100%; opacity: 1; background-color: rgba(0, 0, 0, 0.5);cursor: zoom-out;`;
      lightImg.style = `width: ${width}px;border-radius: 2px;`;
      lightImg.onclick = function () {
        lightBox.style = '';
        this.remove();
      }
      lightBox.append(lightImg);
    }
  })
</script>
  </div>
</body>

<div class="search-mask" id="search_mask" style="display: none;">
  <div class="search-box">
    <div class="search-title">
      <i class="fa fa-search"></i>
      <div class="input-box">
        <input id="search" type="text" class="language" data-lan="search" placeholder="搜索">
      </div>
      <i id="close" class="fa fa-times-circle"></i>
    </div>
    <div class="stat-box">
      <span id="stat_count">0</span><span class="language" data-lan="stat">条相关条目，使用了</span><span id="stat_times">0</span><span class="language" data-lan="stat-time">毫秒</span>
      <hr>
    </div>
    <div class="result" id="result">
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/vue3-xin-te-xing-zhi-teleport/"" data-c="
          &lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;Vue3发布的消息牵动着每一个前端er的心，终于在18号，尤大发布了3.0，作为一个夜猫子，也是第一时间就得到了消息，根据尤大的说法，新版本的中文翻译已经差不多了，而网络上对于3.0的教程也出了不少，尤其是这几天，各路大神对于vue3.0也是各种解析，本系列就是博彩各路大神之长，将他们对于vue3.0的介绍汇总整理。&lt;/p&gt;
&lt;h2 id=&#34;teleport&#34;&gt;Teleport&lt;/h2&gt;
&lt;p&gt;Teleport 是一种能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置的技术，就有点像哆啦A梦的“任意门”&lt;/p&gt;
&lt;p&gt;场景：像 modals,toast 等这样的元素，很多情况下，我们将它完全的和我们的 Vue 应用的 DOM 完全剥离，管理起来反而会方便容易很多&lt;/p&gt;
&lt;p&gt;原因在于如果我们嵌套在 Vue 的某个组件内部，那么处理嵌套组件的定位、z-index 和样式就会变得很困难&lt;/p&gt;
&lt;p&gt;另外，像 modals,toast 等这样的元素需要使用到 Vue 组件的状态（data 或者 props）的值&lt;/p&gt;
&lt;p&gt;这就是 Teleport 派上用场的地方。我们可以在组件的逻辑位置写模板代码，这意味着我们可以使用组件的 data 或 props。然后在 Vue 应用的范围之外渲染它&lt;/p&gt;
&lt;h2 id=&#34;teleport的使用&#34;&gt;Teleport的使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;teleport&amp;gt;&lt;/code&gt;向Vue核心添加组件&lt;/li&gt;
&lt;li&gt;该组件需要一个目标元素，该元素是通过需要一个HTMLElement或querySelector字符串的prop提供的。&lt;/li&gt;
&lt;li&gt;组件将其子代移动到DOM选择器标识的元素&lt;/li&gt;
&lt;li&gt;在虚拟DOM级别，子级仍然是子代的后代&lt;teleport&gt;，因此他们可以从其祖先那里获得注入&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;body&amp;gt;
  &amp;lt;div id=&amp;quot;app&amp;quot;&amp;gt;
    &amp;lt;h1&amp;gt;Move the #content with the portal component&amp;lt;/h1&amp;gt;
    &amp;lt;teleport to=&amp;quot;#endofbody&amp;quot;&amp;gt;
      &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;
        &amp;lt;p&amp;gt;
          this will be moved to #endofbody.&amp;lt;br /&amp;gt;
          Pretend that it&#39;s a modal
        &amp;lt;/p&amp;gt;
        &amp;lt;Child /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/teleport&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div id=&amp;quot;endofbody&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;script&amp;gt;
    new Vue({
      el: &amp;quot;#app&amp;quot;,
      components: {
        Child: { template: &amp;quot;&amp;lt;div&amp;gt;Placeholder&amp;lt;/div&amp;gt;&amp;quot; }
      }
    });
  &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将导致以下行为：&lt;/p&gt;
&lt;p&gt;1 &lt;code&gt;&amp;lt;teleport&amp;gt;&lt;/code&gt;在此示例中：&lt;code&gt;&amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&lt;/code&gt;和&lt;code&gt;&amp;lt;Child /&amp;gt;&lt;/code&gt;的所有子项都将附加到&lt;code&gt;&amp;lt;div id=&amp;quot;endofbody&amp;quot;&amp;gt;&lt;/code&gt;&lt;br&gt;
2 &lt;code&gt;&amp;lt;Child&amp;gt;&lt;/code&gt;作为这些子项之一的组件将保留为&lt;code&gt;&amp;lt;teleport&amp;gt;&lt;/code&gt;的父项的子项（&lt;code&gt;&amp;lt;teleport&amp;gt;&lt;/code&gt;透明）。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;app&amp;quot;&amp;gt;
  &amp;lt;!-- --&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div id=&amp;quot;endofbody&amp;quot;&amp;gt;
  &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      this will be moved to #endofbody.&amp;lt;br /&amp;gt;
      Pretend that it&#39;s a modal
    &amp;lt;/p&amp;gt;
    &amp;lt;div&amp;gt;Placeholder&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;感谢&#34;&gt;感谢&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://zhuanlan.zhihu.com/p/143042237?from_voters_page=true&#34;&gt;志学python&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;https://www.jianshu.com/p/1ecf5006b1ae&#34;&gt;GpingFeng&lt;/a&gt;&lt;/p&gt;
">Vue3新特性之——Teleport</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-wei-qian-duan/"" data-c="
          &lt;h2 id=&#34;什么是微前端&#34;&gt;什么是微前端？&lt;/h2&gt;
&lt;p&gt;微前端（Micro-Frontends）是一种类似于微服务的架构，它将微服务的理念应用于浏览器端，即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立运行、独立开发、独立部署。微前端不是单纯的前端框架或者工具，而是一套架构体系，这个概念最早在2016年底被提出，可以参考在Google上搜索Micro-Frontends, 排名靠前的micro-frontends.org的博客文章，提出了早期的微前端模型。&lt;/p&gt;
&lt;h2 id=&#34;为什么会有微前端&#34;&gt;为什么会有微前端&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;任何新技术的产生都是为了解决现有场景和需求下的技术痛点，微前端也不例外：&lt;br&gt;
拆分和细化：当下前端领域，单页面应用（SPA）是非常流行的项目形态之一，而随着时间的推移以及应用功能的丰富，单页应用变得不再单一而是越来越庞大也越来越难以维护，往往是改一处而动全身，由此带来的发版成本也越来越高。微前端的意义就是将这些庞大应用进行拆分，并随之解耦，每个部分可以单独进行维护和部署，提升效率。&lt;/li&gt;
&lt;li&gt;整合历史系统：在不少的业务中，或多或少会存在一些历史项目，这些项目大多以采用老框架类似（Backbone.js，Angular.js 1）的B端管理系统为主，介于日常运营，这些系统需要结合到新框架中来使用还不能抛弃，对此我们也没有理由浪费时间和精力重写旧的逻辑。而微前端可以将这些系统进行整合，在基本不修改来逻辑的同时来同时兼容新老两套系统并行运行。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;实现微前端有哪些方案&#34;&gt;实现微前端有哪些方案&lt;/h2&gt;
&lt;p&gt;单纯根据对概念的理解，很容易想到实现微前端的重要思想就是将应用进行拆解和整合，通常是一个父应用加上一些子应用，那么使用类似Nginx配置不同应用的转发，或是采用iframe来将多个应用整合到一起等等这些其实都属于微前端的实现方案，他们之间的对比如下图：&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1600594986903.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
上述方案中，每种都有自己的优劣，最原始的Nginx配置反向代理是从接入层的角度来将系统进行分离，但是需要运维配置，而iframe嵌套是最简单和最快速的方案，但是iframe的弊端也是无法避免的，而Web Components的方案则需要大量的改造成本，最后的组合式应用路由分发方案改造成本中等并且能满足大部分需求，也不影响各前端应用的体验，是当下各个业务普遍采用的一种方案。&lt;/p&gt;
&lt;h2 id=&#34;是否要用微前端&#34;&gt;是否要用微前端&lt;/h2&gt;
&lt;p&gt;微前端帮助开发者解决了实际的问题，但是对于每个业务来说，是否适合使用微前端，以及是否正确的使用微前端，还是需要遵循以下一些原则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;微前端最佳的使用场景是一些B端的管理系统，既能兼容集成历史系统，也可以将新的系统集成进来，并且不影响原先的交互体验。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;整体的微前端不仅仅是只将系统集成进来，而是整个微前端体系的完善，这其中就包括：&lt;br&gt;
1)：基座应用和微应用的自动部署能力。&lt;br&gt;
2)：微应用的配置管理能力。&lt;br&gt;
3)：本地开发调试能力。&lt;br&gt;
4)：线上监控和统计能力等等。&lt;br&gt;
只有将整个能力体系搭建完善，才能说是整个微前端体系流程的完善。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当发现使用微前端反而使效率变低，简单的变更复杂那就说明微前端并不适用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;作者：吕小鸣&lt;br&gt;
链接：&lt;a href=&#34;https://juejin.im/post/6844904162509979662&#34;&gt;https://juejin.im/post/6844904162509979662&lt;/a&gt;&lt;br&gt;
来源：掘金&lt;/p&gt;
">每天一个名词解释—微前端</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/promise-xiang-guan/"" data-c="
          &lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;promise是ES6新增的，用于处理异步编程，在ES6之前，当ajax请求中出现数据依赖关系的时候，就需要写多层回调，产生“回调地狱”，而promise的出现解决了这个问题，能写出更加优雅的异步代码。&lt;/p&gt;
&lt;h2 id=&#34;promise原理与基本语法&#34;&gt;Promise原理与基本语法&lt;/h2&gt;
&lt;h3 id=&#34;一-promise原理&#34;&gt;一、Promise原理&lt;/h3&gt;
&lt;p&gt;Promise是一种对异步操作的封装，添加了对异步操作执行成功、失败时的方法，主流的规范是Promise/A+。&lt;br&gt;
Promise中有几个状态：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pending:等待中，或者进行中，表示还没有得到结果&lt;/li&gt;
&lt;li&gt;resolved(Fulfilled): 已经完成，表示得到了我们想要的结果，可以继续往下执行&lt;/li&gt;
&lt;li&gt;rejected: 也表示得到结果，但是由于结果并非我们所愿，因此拒绝执行&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1600438117168.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
这三种状态不受外界影响，而且状态只能从pending改变为resolved或者rejected，并且不可逆。在Promise对象的构造函数中，将一个函数作为第一个参数。而这个函数，就是用来处理Promise的状态变化。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;二-promise的基本语法&#34;&gt;二、Promise的基本语法&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Promise实例必须实现then这个方法&lt;/li&gt;
&lt;li&gt;then()必须可以接收两个函数作为参数&lt;/li&gt;
&lt;li&gt;then()返回的必须是一个Promise实例&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;let p1 = new Promise((resolve,reject)=&amp;gt;{
  console.log(1);
  resolve(&#39;浪里行舟&#39;)
  console.log(2)
})
// then:设置成功或者失败后处理的方法
p1.then(result=&amp;gt;{
 //p1延迟绑定回调函数
  console.log(&#39;成功 &#39;+result)
},reason=&amp;gt;{
  console.log(&#39;失败 &#39;+reason)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为then方法的执行结果会返回一个Promise对象，所以可以通过then进行链式执行，通过这种方式解决“回调地狱”。&lt;/p&gt;
&lt;h3 id=&#34;三-错误处理&#34;&gt;三、错误处理&lt;/h3&gt;
&lt;p&gt;上面的例子中，是通过then返回的第二个函数进行错误处理，而Promise对象的错误具有“冒泡”的性质，会一直向后传递，直到被捕获，所以可以不用在单个Promise对象中单独捕获。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function executor (resolve, reject) {
  let rand = Math.random()
  console.log(1)
  console.log(rand)
  if (rand &amp;gt; 0.5) {
    resolve()
  } else {
    reject()
  }
}
var p0 = new Promise(executor)
var p1 = p0.then((value) =&amp;gt; {
  console.log(&#39;succeed-1&#39;)
  return new Promise(executor)
})
var p2 = p1.then((value) =&amp;gt; {
  console.log(&#39;succeed-2&#39;)
  return new Promise(executor)
})
p2.catch((error) =&amp;gt; {
  console.log(&#39;error&#39;, error)
})
console.log(2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面的例子中，就把错误通过p2.catch处理了。&lt;/p&gt;
&lt;h3 id=&#34;四-链式调用&#34;&gt;四、链式调用&lt;/h3&gt;
&lt;p&gt;Promise可以链接到一起，表示一系列的异步步骤。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let p1=new Promise((resolve,reject)=&amp;gt;{
    resolve(100) // 决定了下个then中成功方法会被执行
})
// 连接p1
let p2=p1.then(result=&amp;gt;{
    console.log(&#39;成功1 &#39;+result)
    return Promise.reject(1) 
// 返回一个新的Promise实例，决定了当前实例是失败的，所以决定下一个then中失败方法会被执行
},reason=&amp;gt;{
    console.log(&#39;失败1 &#39;+reason)
    return 200
})
// 连接p2 
let p3=p2.then(result=&amp;gt;{
    console.log(&#39;成功2 &#39;+result)
},reason=&amp;gt;{
    console.log(&#39;失败2 &#39;+reason)
})
// 成功1 100
// 失败2 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过p1传递resolve(100)给p2，p2执行result并且打印“成功1 100”，p2则返回传递reject(1)给p3，所以p3会打印“失败2 1”&lt;/p&gt;
&lt;h2 id=&#34;promise常用方法&#34;&gt;Promise常用方法&lt;/h2&gt;
&lt;h3 id=&#34;promiseall&#34;&gt;Promise.all()&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;let p1 = Promise.resolve(1)
let p2 = new Promise(resolve =&amp;gt; {
  setTimeout(() =&amp;gt; {
    resolve(2)
  }, 1000)
})
let p3 = Promise.resolve(3)
Promise.all([p3, p2, p1])
  .then(result =&amp;gt; {
 // 返回的结果是按照Array中编写实例的顺序来
    console.log(result) // [ 3, 2, 1 ]
  })
  .catch(reason =&amp;gt; {
    console.log(&amp;quot;失败:reason&amp;quot;)
  })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Promise.all()方法需要一个数组参数，数组内则是多个Promise对象，只有当数组内所有Promise对象的状态都变为resolved或rejected时，才调用then方法。&lt;/p&gt;
&lt;h3 id=&#34;promiserace&#34;&gt;Promise.race()&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;function renderRace() {
    return Promise.race([getJSON(url), getJSON(url1)]);
}

renderRace().then(function(value) {
    console.log(value);
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;与all类似，Promise.race()方法也需要一个数组作为参数，区别在于Promise.race()方法只要有一个数组中的Promise对象状态改变，无论是resolved还是rejected，都直接调用then方法。&lt;/p&gt;
&lt;h2 id=&#34;后记&#34;&gt;后记&lt;/h2&gt;
&lt;p&gt;Promise使用是非常频繁的，并且最近的几次更新中也新增了一些Promise的新方法，还有Async/await这次来不及总结，之后会汇总进来，还有Promise涉及到宏任务与微任务，也是之后要整理的，这篇文章也是多次用到了参考中几位前辈的图片以及代码，深表感谢。&lt;/p&gt;
&lt;h2 id=&#34;参考&#34;&gt;参考&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/ljianshu/Blog/issues/81&#34;&gt;你真的懂Promise吗&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;https://yangbo5207.github.io/wutongluo/ji-chu-jin-jie-xi-lie/shi-san-3001-promise.html&#34;&gt;Promise&lt;/a&gt;&lt;/p&gt;
">Promise相关</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/shi-jian-xiang-guan/"" data-c="
          &lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;事件委托是前端面试必考内容，在工作中也是经常使用，所以我就对事件以及相关的操作做一下简单的梳理。&lt;/p&gt;
&lt;h2 id=&#34;事件事件流&#34;&gt;事件，事件流&lt;/h2&gt;
&lt;h3 id=&#34;事件&#34;&gt;事件&lt;/h3&gt;
&lt;p&gt;JS高程第三版中，第十三章详细的介绍了事件，其中提到，JS与HTML之间的交互是通过事件实现的，事件，就是文档或浏览器窗口中发生的一些特定的交互瞬间。&lt;/p&gt;
&lt;h3 id=&#34;事件流&#34;&gt;事件流&lt;/h3&gt;
&lt;p&gt;事件流描述的是从页面中接收事件的顺序，而今天我们所熟知的冒泡与捕获事件，其实是IE与Netscape基于自己的认知提出的完全相反的事件流概念，IE的是冒泡，网景的是捕获。&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1600262228942.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;事件三要素&#34;&gt;事件三要素&lt;/h3&gt;
&lt;p&gt;我们知道，事件不是独自存在的，它由这三个要素构成：事件源、事件、事件驱动程序。&lt;br&gt;
事件一般有以下几种(偷懒放图)&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1600261807248.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
事件源就是指发生事件的对象，一般来说是dom元素，所以获取事件源就是获取dom，获取dom有以下几类。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 获取单个
document.getElementById
// 获取多个的组合
document.getElementsByClassName
……
// 获取静态
document.querySelector
……
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获取完事件源，接下来就是绑定事件，这里就不得不提到dom级别。&lt;/p&gt;
&lt;h4 id=&#34;dom0&#34;&gt;dom0&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// 绑定事件
btn.onclick = function () {
    alert(this.id);
}
// 删除事件
btn.onclick = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;dom0级的优点是实现简单，并且具有跨浏览器的优势,缺点是同种事件只能绑定一个，后面的会覆盖前面的，并且事件是在冒泡阶段触发。&lt;/p&gt;
&lt;h4 id=&#34;dom1&#34;&gt;dom1&lt;/h4&gt;
&lt;p&gt;dom1因为一般只有设计规范没有具体实现，所以一般跳过。&lt;/p&gt;
&lt;h4 id=&#34;dom2&#34;&gt;dom2&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;let btn = document.getElementById(&#39;btn&#39;)
    btn.addEventListener(&#39;click&#39;, function () {
    let li = document.createElement(&#39;li&#39;);
    li.innerHTML = i + 1
    i++;
    ul.appendChild(li)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;dom2通过addEventListener绑定事件，并且传递三个参数，分别是要处理的事件名、作为事件处理程序的函数以及一个布尔值，布尔值为true表示在捕获阶段调用事件处理程序；如果是false表示在冒泡阶段调用事件处理程序，默认是false。&lt;/p&gt;
&lt;h4 id=&#34;dom3&#34;&gt;dom3&lt;/h4&gt;
&lt;p&gt;dom3在dom2的基础上添加了更多的事件类型，见下图(再次偷懒)&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1600262059244.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
同时dom3也允许开发人员自定义事件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var myEvent = new Event(&#39;clickTest&#39;);
element.addEventListener(&#39;clickTest&#39;, function () {
    console.log(&#39;smyhvae&#39;);
});

//元素注册事件
element.dispatchEvent(myEvent); //注意，参数是写事件对象 myEvent，不是写 事件名 clickTest
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;事件委托&#34;&gt;事件委托&lt;/h2&gt;
&lt;p&gt;事件委托可以看作是事件最为重要的应用了。就如同它的名字，通俗的将事件委托就是把一个元素响应事件（click、keydown......）的函数委托到另一个元素。各路大牛在讲事件委托时，都使用了取快递来解释：&lt;br&gt;
有三个同事预计会在周一收到快递。为签收快递，有两种办法：一是三个人在公司门口等快递；二是委托给前台小姐姐代为签收。现实当中，我们大都采用委托的方案（公司也不会容忍那么多员工站在门口就为了等快递）。前台小姐姐收到快递后，她会判断收件人是谁，然后按照收件人的要求签收，甚至代为付款。这种方案还有一个优势，那就是即使公司里来了新员工，前台小姐姐也会在收到寄给新员工的快递后核实并代为签收。&lt;br&gt;
其中还包含两种意思：&lt;br&gt;
---- 委托前台的同事可以是可以代为签收的，即程序中的dom节点有事件&lt;br&gt;
---- 新来的员工可以委托前台代签，即程序中新添加的dom节点也会有事件&lt;br&gt;
事件委托是利用冒泡来实现的，事件委托的优点有：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;减少事件的绑定次数，减少内存消耗&lt;/li&gt;
&lt;li&gt;动态绑定事件&lt;br&gt;
例子：点击按钮新增li，点击li可以给li增加红色背景色&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;// html
&amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;1&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;2&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;3&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;4&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;5&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;6&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;7&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;8&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;9&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;10&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;input type=&amp;quot;button&amp;quot; id=&amp;quot;btn&amp;quot; value=&amp;quot;添加&amp;quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//js
let i = 10;
let btn = document.querySelector(&#39;#btn&#39;);
let ul = document.getElementsByTagName(&#39;ul&#39;)[0];
btn.addEventListener(&#39;click&#39;, function () {
    let li = document.createElement(&#39;li&#39;);
    li.innerHTML = i + 1;
    i++;
    ul.appendChild(li)
})
ul.addEventListener(&#39;click&#39;, function (event) {
    event = event || window.event;
    if (event.target.nodeName.toLowerCase() == &#39;li&#39;) {
        event.target.style.backgroundColor = &#39;red&#39;
        }
}, false)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// jquery写法
$(&#39;#btn&#39;).on(&#39;click&#39;, function (event) {
    let li = document.createElement(&#39;li&#39;);
    $(&#39;ul&#39;).append(li)
})
$(&#39;ul&#39;).on(&#39;click&#39;, &#39;li&#39;, function (event) {
    var target = $(event.target);
    target.css({
        &#39;backgroundColor&#39;: &#39;red&#39;
    })
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再写一个简易的拖拽div&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// css
.div {
    width: 100px;
    height: 100px;
    position: absolute;
    left: 0;
    top: 0;
    background-color: tomato;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// html
&amp;lt;div class=&amp;quot;div&amp;quot; id=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;let div = document.getElementById(&#39;div&#39;)
div.onclick = function (event) {
    console.log(event)
}
div.addEventListener(&#39;mousedown&#39;, start)

function start() {
    div.addEventListener(&#39;mousemove&#39;, move)
    div.addEventListener(&#39;mouseup&#39;, stop)
}

function move(event) {
    div.style.left = event.clientX - 50 + &#39;px&#39;
    div.style.top = event.clientY - 50 + &#39;px&#39;
}

function stop(event) {
    div.removeEventListener(&#39;mousemove&#39;, move)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;event常用属性方法&lt;br&gt;
event.preventDefault()&lt;br&gt;
作用：阻止默认事件&lt;br&gt;
event.stopPropagation()&lt;br&gt;
作用：阻止冒泡&lt;br&gt;
event.cancelBubble = true&lt;br&gt;
兼容低版本&lt;br&gt;
offsetX/offsetY&lt;br&gt;
offsetX/Y获取到是触发点相对被触发dom的左上角距离，不过左上角基准点在不同浏览器中有区别，以内容区左上角为基准点（不包括边框），如果触发点在边框上会返回负值，&lt;br&gt;
pageX/pageY&lt;br&gt;
pageX/Y获取到的是触发点相对文档区域左上角距离，会随着页面滚动而改变。&lt;br&gt;
clientX/Y&lt;br&gt;
event的clientX，clientY属性分别表示鼠标点击位置相对于文档的左边距，上边距，不随页面滚动而改变。&lt;br&gt;
target,currentTarget&lt;br&gt;
target是事件的真正发出者&lt;br&gt;
currentTarget始终是监听事件者&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;事件并不算难，需要记住的是事件模型与事件流，尤其是捕获与冒泡的流程，其中捕获起点是从window-&amp;gt;document，冒泡终点是document-&amp;gt;window，事件委托要记住几个事件以及兼容性。&lt;/p&gt;
">事件相关</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/emment-yu-fa-vscode-kuai-jie-fang-shi/"" data-c="
          &lt;h3 id=&#34;1生成html5代码&#34;&gt;1.生成HTML5代码&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;!-- ! 或者 html:5 --&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;2生成子代元素&#34;&gt;2.生成子代元素：( &amp;gt; )&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- div&amp;gt;p&amp;gt;span --&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;p&amp;gt;
        &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;3生成兄弟元素&#34;&gt;3.生成兄弟元素：( + )&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- div+p+h2 --&amp;gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;&amp;lt;/h2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;4生成多个元素&#34;&gt;4.生成多个元素： ( * )&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- div&amp;gt;p*2+div*3 --&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;5生成上一个层级的元素&#34;&gt;5.生成上一个层级的元素：( ^ )&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- div&amp;gt;p^div --&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;!-- div&amp;gt;p&amp;gt;span^^h2+strong --&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;p&amp;gt;
        &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;h2&amp;gt;&amp;lt;/h2&amp;gt;
&amp;lt;strong&amp;gt;&amp;lt;/strong&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;6对元素进行分组-使用-括号分组&#34;&gt;6.对元素进行分组( 使用() 括号分组 )&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- (div&amp;gt;p&amp;gt;span)+h2+strong --&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;p&amp;gt;
        &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;h2&amp;gt;&amp;lt;/h2&amp;gt;
&amp;lt;strong&amp;gt;&amp;lt;/strong&amp;gt;

&amp;lt;!-- div&amp;gt;(p&amp;gt;span)+h2+a--&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;p&amp;gt;
        &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/p&amp;gt;
    &amp;lt;h2&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;a&amp;gt;&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;7生成元素属性id属性class属性普通属性&#34;&gt;7.生成元素属性(id属性，class属性，普通属性)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!--id: div#main --&amp;gt;
&amp;lt;div id=&#39;main&#39;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;!--class: div.box --&amp;gt;
&amp;lt;div class=&#39;box&#39;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;!--普通属性: div[title] --&amp;gt;
&amp;lt;div class=&#39;&#39;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;!--普通属性赋值: div[title=&#39;文字内容&#39;] --&amp;gt;
&amp;lt;div title=&#39;文字内容&#39;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!--div#header&amp;gt;div.box1^div.page+div#footer--&amp;gt;
&amp;lt;div id=&#39;header&#39;&amp;gt;
    &amp;lt;div class=&#39;box1&#39;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&#39;page&#39;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div id=&#39;footer&#39;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;8生成元素的文字-使用-花括号&#34;&gt;8.生成元素的文字( 使用{} 花括号 )&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!--div#box{div文字内容}--&amp;gt;
&amp;lt;div id=&#39;box&#39;&amp;gt;div文字内容&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;9生成结构中有数字-使用-符号&#34;&gt;9.生成结构中有数字( 使用 $ 符号)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- 属性中有数字: div.box$*3--&amp;gt;
&amp;lt;div class=&amp;quot;box1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;box2&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;box3&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;!-- 属性中的数字中有多个0: ul&amp;gt;li.item$$$*3 --&amp;gt;
&amp;lt;ul&amp;gt;
    &amp;lt;li class=&amp;quot;item001&amp;quot;&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li class=&amp;quot;item002&amp;quot;&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li class=&amp;quot;item003&amp;quot;&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;!-- 内容中有数字: div{第$行内容}*3 --&amp;gt;
&amp;lt;div&amp;gt;第1行内容&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;第2行内容&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;第3行内容&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;10隐式标签&#34;&gt;10.隐式标签&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- 第一种: #header&amp;gt;.box (默认以 div 形式展示)--&amp;gt;
&amp;lt;div id=&amp;quot;header&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- 第二种 ul&amp;gt;.item${文本内容$}*3 (ul中 默认是 li)--&amp;gt;
&amp;lt;ul&amp;gt;
    &amp;lt;li class=&amp;quot;item1&amp;quot;&amp;gt;文本内容1&amp;lt;/li&amp;gt;
    &amp;lt;li class=&amp;quot;item2&amp;quot;&amp;gt;文本内容2&amp;lt;/li&amp;gt;
    &amp;lt;li class=&amp;quot;item3&amp;quot;&amp;gt;文本内容3&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- 第三种 table&amp;gt;#row$*3&amp;gt;[colspan=2]--&amp;gt;
&amp;lt;table&amp;gt;
    &amp;lt;tr id=&amp;quot;row1&amp;quot;&amp;gt;
        &amp;lt;td colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;tr id=&amp;quot;row2&amp;quot;&amp;gt;
        &amp;lt;td colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;tr id=&amp;quot;row3&amp;quot;&amp;gt;
        &amp;lt;td colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;11css中的emment语法&#34;&gt;11.CSS中的Emment语法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;/* w100+h100+m0+p0 */
div{
    width: 100px;
    height: 100px;
    margin: 0;
    padding: 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* m20-30-40-50 分别是上,右,下,左*/
div{
    margin: 20px 30px 40px 50px;
}

/* p-10-20--30 分别是上-10,右和左20,下-30*/
div{
    padding: -10px 20px -30px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;/* m10px20px   m10px-20*/
div{
    margin:10px  20px;
    margin:10px -20px;
}

/*dib  fz20  fz1.5  fw400  lh20px(行高必须加单位)*/
div{
    display: inline-block;
    font-size:20px;
    font-size:1.5em;
    font-weight:400;
    line-height:20px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;转载于 &lt;a href=&#34;https://www.cnblogs.com/rans/p/12804016.html&#34;&gt;白邪&lt;/a&gt;&lt;/p&gt;
">Emment语法（vscode快捷方式）</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/fei-chang-jian-dan-de-fang-dou-he-jie-liu/"" data-c="
          &lt;p&gt;防抖和节流是面试前端必考的内容，之前也总结过防抖和节流，但是最近又看到了一个非常简单的防抖和节流的代码，给大家看一下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function debounce(fn,delay){
    var timer = null;
    return function(){
        var firstClick = !timer;
        if (timer) {
            clearTimeout(timer);
        }
        if(firstClick){
            fn.apply(this,arguments)
        }
        timer = setTimeout(function(){
            timer = null;
        },delay)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function throttle(fn,delay){
    var old = 0;
    return function(){
        var new = new Date().getTime();
        if(new -old &amp;gt; daley){
            fn.apply(this,arguments)
            old = new;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;防抖的代码还可以使用箭头函数再简化一下，第一次看到这个代码的时候我没有想到竟然还能这么写。&lt;/p&gt;
">非常简单的防抖和节流</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/qian-duan-mo-kuai-hua-jian-jie/"" data-c="
          &lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;前端模块化是个进几年常被提起的词，随着大前端的盛行，前端模块化也越来越被广泛应用，但其实前端模块化是早就存在的，但是随着时间的推移，技术不断进步，模块化的方式也在不断变化，本文就大致梳理一下前端模块化。&lt;/p&gt;
&lt;h2 id=&#34;什么是模块模块化模块化开发&#34;&gt;什么是模块？模块化？模块化开发？&lt;/h2&gt;
&lt;p&gt;模块，是为了完成某个功能所需的程序。模块是系统中职责单一且可替换的部分。&lt;br&gt;
模块化是把系统代码分为一些列的职责单一且可替换的模块。&lt;br&gt;
模块化开发是指开发新模块和复用旧模块来实现应用功能的开发形式。&lt;/p&gt;
&lt;h2 id=&#34;为什么要模块化&#34;&gt;为什么要模块化？&lt;/h2&gt;
&lt;p&gt;因为随着硬件的发展，web能做的事情也越来越多，很多业务逻辑和交互都通过web实现，随之而来的就是代码量的提升，因此需要模块化开发，模块化开发具有以下的优点。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;避免命名冲突&lt;/li&gt;
&lt;li&gt;更高的复用性与可维护性&lt;/li&gt;
&lt;li&gt;更好的分离，按需加载&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;模块化的发展历程&#34;&gt;模块化的发展历程&lt;/h2&gt;
&lt;h3 id=&#34;洪荒时期&#34;&gt;洪荒时期&lt;/h3&gt;
&lt;p&gt;1999    直接定义依赖（全局function模式）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo(){
    //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;缺点是污染全局变量，每个函数都单独命名，如果有多个函数就过于繁琐&lt;br&gt;
2002    namespace模式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var app = {};
app.foo = function(){
    //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;优点：不在污染全局变量，减少了命名冲突&lt;br&gt;
缺点：依赖唯一的全局变量，并且如果使用同一个全局变量就无法共存&lt;br&gt;
2003    匿名闭包模型（IIFE模式）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(function(window) {
  let data = &#39;www.baidu.com&#39;
  //操作数据的函数
  function foo() {
    //用于暴露函数
    console.log(`foo() ${data}`)
  }
  function bar() {
    //用于暴露函数
    console.log(`bar() ${data}`)
    otherFun() //内部调用
  }
  function otherFun() {
    //内部私有的函数
    console.log(&#39;otherFun()&#39;)
  }
  //暴露行为
  window.myModule = { foo, bar } //ES6写法
})(window)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;缺点在于无法解决模块间的依赖问题&lt;br&gt;
2009    注入依赖模式&lt;br&gt;
这一时期，因为前端才刚刚发展，所以还是很原始的&lt;/p&gt;
&lt;h3 id=&#34;现在所常用的前端模块化方案&#34;&gt;现在所常用的前端模块化方案&lt;/h3&gt;
&lt;p&gt;CommonJS&lt;br&gt;
特点：所有代码运行在模块作用域，不会污染全局变量，模块可以多次加载，但只在第一次直接读取缓存，想让模块再次运行必须清除缓存。模块加载顺序取决于在代码中的顺序。nodejs就是采用这种模式&lt;br&gt;
基本语法：&lt;br&gt;
暴露模块：&lt;br&gt;
&lt;code&gt;module.exports = value&lt;/code&gt;或&lt;code&gt;exports.xxx = value&lt;/code&gt;&lt;br&gt;
引入模块：&lt;br&gt;
&lt;code&gt;require(xxx)&lt;/code&gt;&lt;br&gt;
重点：CommonJS的加载机制是，引入的是被输出的值的拷贝，一旦输出，模块内部的变化无法影响这个值。&lt;br&gt;
AMD&lt;br&gt;
特点：异步&lt;br&gt;
基本语法：&lt;br&gt;
暴露模块：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 定义没有依赖的模块
define(function(){
    return 模块
})
// 定义有依赖的模块
define([&#39;module1&#39;,&#39;module2&#39;],function(m1,m2){
    return 模块
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;引入使用模块&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require([&#39;module1&#39;,&#39;module2&#39;],function(m1,m2){
    使用 m1/m2
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CMD&lt;br&gt;
基本语法：&lt;br&gt;
定义暴露模块：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 定义无依赖模块
define(function(require,exports,module){
    exports.xxx = value;
    module.exports = value;
})
// 定义有依赖模块
define(function(require,exports,module){
    var module2 = require(&#39;./module2&#39;);
    require.async(&#39;./module3&#39;,function(m3){
        // ...
    })
    exports.xxx = value
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;引入使用模块：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define(function (require) {
  var m1 = require(&#39;./module1&#39;)
  var m4 = require(&#39;./module4&#39;)
  m1.show()
  m4.show()
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ES6模块化&lt;br&gt;
ES6模块化是我接触前端以来接触到的最多的一个，基本各个技术文档关于使用的部分也都是import、export之类的，并且网上的文章很多都是花费最多篇幅介绍ES6模块化，想来这应该是最为广泛使用的一种前端模块化规范了。&lt;br&gt;
语法：&lt;br&gt;
export：用于规定模块的对外接口&lt;br&gt;
import：用于引入其他模块提供的功能&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// libs.js
export let counter = 3;

// main.js
import {counter} from &#39;./libs&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;定义模块代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//module1.js文件
// 分别暴露
export function foo() {
  console.log(&#39;foo() module1&#39;)
}
export function bar() {
  console.log(&#39;bar() module1&#39;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//module2.js文件
// 统一暴露
function fun1() {
  console.log(&#39;fun1() module2&#39;)
}
function fun2() {
  console.log(&#39;fun2() module2&#39;)
}
export { fun1, fun2 }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//module3.js文件
// 默认暴露 可以暴露任意数据类项，暴露什么数据，接收到就是什么数据
export default () =&amp;gt; {
  console.log(&#39;默认暴露&#39;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;es6模块与commonjs模块对比&#34;&gt;ES6模块与CommonJS模块对比&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;CommonJS输出的是值的拷贝，而ES6modules输出的是值的引用&lt;/li&gt;
&lt;li&gt;CommonJS是运行时加载，而ES6modules是编译时输出接口&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;前端模块化的进程伴随着前端的发展，也许几年后又是新的方法取代现在的方法，但是目前，ES6模块是能够完全取代CommonJS与CMD等规范的。&lt;/p&gt;
&lt;h2 id=&#34;后记&#34;&gt;后记&lt;/h2&gt;
&lt;p&gt;其实正如文章名字所言，这是一个关于前端模块化的简介，或者说是演变史，关于CMD、AMD等规范的详细内容都没有提及，这也不是现阶段的我需要去了解的，这里只是梳理一下，文章依然是总结了其他大牛的文章，可能总结的还不够好，精华部分可能也被舍弃了，但至少是我自己查阅与思考后的结果。前几天看掘金上不少有多年前端开发经验的前辈在感叹现如今前端发展之快，对前端从业者技能要求也是越来越高，学习前端的资源更是多不胜数，远超他们当年，不由得感谢这些在网络上输出优质内容的前辈们，是他们推动了技术整体的进步，让我想起了大刘的那本《乡村教师》，看到里面外星人感叹人类的文明传承竟是靠言传身教，现如今人们获取知识的途径或许变得简单，但是传播知识的人的精神却丝毫未减。&lt;/p&gt;
&lt;h2 id=&#34;参考文章&#34;&gt;参考文章&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://segmentfault.com/a/1190000017466120&#34;&gt;前端模块化详解(完整版)&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;https://juejin.im/post/6844903640897945614#heading-10&#34;&gt;Javascript模块化的演进历程&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;https://github.com/seajs/seajs/issues/242&#34;&gt;CMD 模块定义规范&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;https://www.iteye.com/blog/zccst-2215317&#34;&gt;CommonJS，AMD，CMD区别&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;https://github.com/seajs/seajs/issues/588&#34;&gt;前端模块化开发那点历史&lt;/a&gt;&lt;/p&gt;
">前端模块化简介</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/kua-yu-xiang-guan/"" data-c="
          &lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;最早接触跨域是在做毕设项目的时候，因为之前做的都是使用THINKPHP的项目，前后端不分离，所以没有遇到过跨域的问题，后来该做前端vue+后端thinkphp才遇到这个问题，但是因为是使用的vue-cli，跨域配置起来很简单，就没有特意去记录，但是因为跨域问题是前后端分离比较常见的问题，所以今天汇总一下。&lt;/p&gt;
&lt;h2 id=&#34;什么是跨域为什么要跨域&#34;&gt;什么是跨域？为什么要跨域？&lt;/h2&gt;
&lt;p&gt;首先，跨域指的是从一个域名去请求另一个域名的数据，这不够严谨，因为只要不是同协议、同域名、同端口的请求都算作跨域。&lt;br&gt;
其次，为什么要跨域？是因为浏览器的同源策略。&lt;br&gt;
同源策略，是为了保证用户的信息安全，防止信息被恶意窃取。如果没有同源策略，当访问A网站后如果访问B网站，那么B网站就可以读取A网站上的Cookie，用户的安全就受到了极大的威胁，所以同源策略是必须的。&lt;/p&gt;
&lt;h2 id=&#34;同源是哪些相同呢&#34;&gt;同源是哪些相同呢？&lt;/h2&gt;
&lt;p&gt;同源指的是三个相同&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;协议相同&lt;/li&gt;
&lt;li&gt;域名相同&lt;/li&gt;
&lt;li&gt;端口相同&lt;br&gt;
只有符合这三个，才是符合同源策略的。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;同源策略限制了什么呢&#34;&gt;同源策略限制了什么呢？&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;cookie、localstorage、indexDB无法获取&lt;/li&gt;
&lt;li&gt;Dom无法获取&lt;/li&gt;
&lt;li&gt;AJAX请求不能发送&lt;br&gt;
我前面提到的前后端分离要配置跨域，就是为了解决ajax的问题。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;问题知道了那怎么解决呢&#34;&gt;问题知道了，那怎么解决呢？&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;JSONP&lt;/li&gt;
&lt;li&gt;CORS&lt;/li&gt;
&lt;li&gt;WebSocket&lt;/li&gt;
&lt;li&gt;Post Message&lt;br&gt;
以上几种方式，我只使用过1、2来解决跨域问题。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;jsonp&#34;&gt;JSONP&lt;/h2&gt;
&lt;p&gt;这是最简单的一种解决方式，利用&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;标签不受跨域的限制，让&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;指向一个地址并提供一个回调函数来接收数据，简单且兼容性好，缺点在于只限GET请求。&lt;br&gt;
前端&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;
var callback = (resp) =&amp;gt; {
      console.log(resp)
}
&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;quot;http:localhost:3000/jsonp?callback=callback&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;服务端&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.get(&#39;/jsonp&#39;, function(req, res, next) {
	res.jsonp(
		&#39;hello 这是一个jsonP跨域&#39;
	);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例子中我使用了express作为服务器，res.jsonp应该是express专门为jsonp做的，后端会将hello 这是一个jsonP跨域这串字符返回，前端接收到以后调用名为callback的函数，处理数据。&lt;/p&gt;
&lt;h2 id=&#34;cors&#34;&gt;CORS&lt;/h2&gt;
&lt;p&gt;cors全称是cross-site resource sharing，跨域资源共享，是为了解决跨域问题存在的。&lt;br&gt;
它有两种请求类型：简单请求和非简单请求&lt;br&gt;
只要同时满足以下两大条件就属于简单请求&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;请求方法是以下三种之一&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;head&lt;/li&gt;
&lt;li&gt;get&lt;/li&gt;
&lt;li&gt;post&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;HTTP的头信息不超出以下几种字段&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Accept&lt;/li&gt;
&lt;li&gt;Accept-Language&lt;/li&gt;
&lt;li&gt;Content-Language&lt;/li&gt;
&lt;li&gt;Last-Event-Id&lt;/li&gt;
&lt;li&gt;Content-Type：只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain&lt;br&gt;
简单请求前端无需任何处理，如果需要携带cookie，前后端都设置一下就可以了。&lt;br&gt;
复杂请求因为各个后端设置不同，所以就不详细介绍了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;websocket&#34;&gt;WebSocket&lt;/h2&gt;
&lt;p&gt;websocket我也没有使用过，不过稍微用过一下PHPsocket框架Workerman,因为打算在毕设里加入个聊天功能，一开始找vue相关的推荐的全是websocket，但是因为已经完成大半了，没法换到nodejs，所以作罢了。不过我看了一下，两者思路差不多，都是先建立连接，对话，最后再关闭对话，期间好像还要监听通讯是否保持通讯，好像是叫做心跳。其间也看到很多在socket出现之前的通讯方法，长轮询和短轮询，通过ajax来进行通讯。&lt;/p&gt;
&lt;h2 id=&#34;postmessage&#34;&gt;postMessage&lt;/h2&gt;
&lt;p&gt;postMessage也是H5提供的方法，我这里找了一个网上的例子&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 发送消息端
window.parent.postMessage(&#39;message&#39;, &#39;http://test.com&#39;)
// 接收消息端
var mc = new MessageChannel()
mc.addEventListener(&#39;message&#39;, event =&amp;gt; {
  var origin = event.origin || event.originalEvent.origin
  if (origin === &#39;http://test.com&#39;) {
    console.log(&#39;验证通过&#39;)
  }
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上的是在开发环境中的跨域方式，按照今天看到的说法，在生产环境中以上方式是不行的，需要使用ngnix代理。&lt;/p&gt;
&lt;h2 id=&#34;ngnix&#34;&gt;NGNIX&lt;/h2&gt;
&lt;p&gt;ngnix配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server{
    # 监听9099端口
    listen 9099;
    # 域名是localhost
    server_name localhost;
    #凡是localhost:9099/api这个样子的，都转发到真正的服务端地址http://localhost:9871 
    location ^~ /api {
        proxy_pass http://localhost:9871;
    }    
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;后记&#34;&gt;后记&lt;/h2&gt;
&lt;p&gt;终于写了一遍篇幅较长的，比较像样的文章了，虽然也是拾人牙慧，但是也比之前要么简短、要么长篇复制、要么不知所云的好不少，尤其是写完之后的满足感，希望能够继续保持。&lt;/p&gt;
">跨域相关</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/tiobe-2020-nian-9-yue-bian-cheng-yu-yan-pai-xing/"" data-c="
          &lt;p&gt;9月的已更新……&lt;/p&gt;
&lt;p&gt;TIOBE 已公布 2020 年 9 月的编程语言排行榜。&lt;/p&gt;
&lt;p&gt;在本期榜单中指数没有明显的变化,值得注意的是,java占有率继续下降,从上个月的14.43%降到13.48%.&lt;/p&gt;
&lt;p&gt;回到2003，编程语言C++是真正的赢家。它在2003年8月达到了17.53%的峰值，并成为2003年编程语言奖的获得者。从那时起，C++就走下坡路。2005年之后，该指数不再触及10%，而在2017年，该指数创下4.55%的历史新低。但是如果与去年相比，C++现在是最快增长的语言（1.48%）。我认为C++ 20标准可能是其中的主要原因之一。&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1599970479933.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;前-10-名编程语言长期走势图&#34;&gt;前 10 名编程语言长期走势图：&lt;/h3&gt;
&lt;figure data-type=&#34;image&#34; tabindex=&#34;1&#34;&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1599970507094.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/figure&gt;
&lt;h3 id=&#34;排名-21-50-的编程语言&#34;&gt;排名 21-50 的编程语言&lt;/h3&gt;
&lt;figure data-type=&#34;image&#34; tabindex=&#34;2&#34;&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1599970524986.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/figure&gt;
&lt;p&gt;作者：醉倾城1&lt;br&gt;
链接：https://www.jianshu.com/p/9f922b829009&lt;br&gt;
来源：简书&lt;/p&gt;
">TIOBE - 2020年9月编程语言排行</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/guang-jian-shu-shi-fa-xian-de-wen-ti/"" data-c="
          &lt;p&gt;今天在简书看文章是，因为要用到控制台，就顺手按了F12，打开了当前页面的控制台，发现有一个打印出来的数组&lt;img src=&#34;https://jujuul.github.io//post-images/1599970226633.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;，虽然都不是什么重要的信息，但是这种打印应该也是不应该的吧&lt;/p&gt;
">逛简书时发现的问题</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/bai-du-sou-suo-ye-geng-xin-liao/"" data-c="
          &lt;p&gt;今天打开百度搜索一点东西，发现搜索结果页变了，变得更加“圆润”、“圆滑”了，字体改变了，下面的分页标签也改了，变成了圆角矩形&lt;img src=&#34;https://jujuul.github.io//post-images/1599819940269.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
页面上文字颜色也改变了，变得更淡了，页面上加载的图片也全都变成圆角矩形了&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1599819914261.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1599819970092.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
同时还有一个&lt;code&gt;border: 1px solid rgba(0,0,0,.05);&lt;/code&gt;边框&lt;br&gt;
我个人觉得，比以前好看多了，虽然以前也用百度，但是对于页面UI之类的不太敏感，所以以前百度什么样子已经忘了，记得前几天在掘金看到有人介绍今年比较流行的新拟态样式，底下有人评论：扁平 - 拟物 - 扁平 - 拟物，风水轮流转，想来人类的审美还是趋同的，就像一个轮回，也许百度以前也是这种圆润风格的页面呢。&lt;/p&gt;
">百度搜索页更新了</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-hippy/"" data-c="
          &lt;h2 id=&#34;前言&#34;&gt;前言：&lt;/h2&gt;
&lt;p&gt;记得之前看过几篇前端跨端框架的文章，里面提到最多的就是uniapp、taro、mpvue，而截至目前，最为主流的应该就是uniapp和taro了，因为使用vue的关系，所以uniapp我也稍微看过，当时就在想，为什么有京东和美团的，不见阿里腾讯的呢？今天码云推送的一篇文章终于提到了，Hippy—腾讯的跨端开发框架。&lt;/p&gt;
&lt;h2 id=&#34;介绍&#34;&gt;介绍：&lt;/h2&gt;
&lt;p&gt;Hippy 是一个新生的跨端开发框架，目标是使开发者可以只写一套代码就直接运行于三个平台（iOS、Android 和 Web）。Hippy 的设计是面向传统 Web 开发者的，特别是之前有过 React Native 和 Vue 的开发者用起来会更为顺手，Hippy 致力于让前端开发跨端 App 更加容易。&lt;/p&gt;
&lt;p&gt;到目前为止，腾讯内已经有了18款流行 App 在使用 Hippy 框架，每日触达数亿用户。&lt;/p&gt;
&lt;h2 id=&#34;特征&#34;&gt;特征：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;为传统 Web 前端设计，官方支持 React 和 Vue 两种主流前端框架。&lt;/li&gt;
&lt;li&gt;不同的平台保持了相同的接口。&lt;/li&gt;
&lt;li&gt;通过 JS 引擎 binding 模式实现的前终端通讯，具备超强性能。&lt;/li&gt;
&lt;li&gt;提供了高性能的可复用列表。&lt;/li&gt;
&lt;li&gt;皆可平滑迁移到 Web 浏览器。&lt;/li&gt;
&lt;li&gt;完整支持 Flex 的布局引擎。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;project-structure&#34;&gt;Project structure：&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Hippy
├── examples                          # 前终端范例代码。
│   ├── hippy-react-demo              # hippy-react 前端范例代码。
│   ├── hippy-vue-demo                # hippy-vue 前端范例代码。
│   ├── ios-demo                      # iOS 终端范例代码。
│   └── android-demo                  # Android 终端范例代码。
├── packages                          # 前端 npm 包。
│   ├── hippy-debug-server            # Hippy 的前终端调试服务。
│   ├── hippy-react                   # Hippy 的 React 语法绑定。
│   ├── hippy-react-web               # hippy-react 转 Web 的库。
│   ├── hippy-vue                     # Hippy 的 Vue 语法绑定。
│   ├── hippy-vue-css-loader          # 用来将 CSS 文本转换为 JS 语法树以供解析的 Webpack loader。
│   ├── hippy-vue-native-components   # hippy-vue 中浏览器中所没有的，额外的，终端定制组件。
│   └── hippy-vue-router              # 在 hippy-vue 中运行的 vue-router。
├── ios
│   └── sdk                           # iOS SDK。
├── android
│   ├── support_ui                    # Android 终端实现的组件。
│   └── sdk                           # Android SDK。
├── core                              # C++ 实现的 JS 模块，通过 Binding 方式运行在 JS 引擎中。
├── layout                            # Hippy 布局引擎。
├── scripts                           # 项目编译脚本。
└── types                             # 全局 Typescript 类型定义。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;结束&#34;&gt;结束：&lt;/h2&gt;
&lt;p&gt;我看了码云和github上最早提交时间都是9个月前，知乎上的提问也是差不多的时间，并且通过网上的讨论度，也能看出这个框架才刚刚开始，不过背后有着腾讯的加持，想来是不会有什么大问题。&lt;/p&gt;
">每天一个名词解释—Hippy</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/vuex-shu-ju-chi-jiu-hua-cha-jian/"" data-c="
          &lt;ol&gt;
&lt;li&gt;安装&lt;br&gt;
&lt;code&gt;npm install vuex-persistedstate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;配置&lt;br&gt;
&lt;code&gt;import persistedState from &#39;vuex-persistedstate&#39;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;export default new Vuex.Store({
    // ...
    plugins: [persistedState()]
})
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;自定义存储方式&lt;br&gt;
vuex-persistedstate默认使用localStorage来固化数据，一些特殊情况要如何应对呢？
&lt;ol&gt;
&lt;li&gt;需要使用sessionStorage的情况&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;plugins: [
persistedState({ storage: window.sessionStorage })
]
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;使用cookie的情况&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import persistedState from &#39;vuex-persistedstate&#39;
import * as Cookies from &#39;js-cookie&#39;

export default new Vuex.Store({
plugins: [
persistedState({
    storage: {
        getItem: key =&amp;gt; Cookies.get(key),
        setItem: (key, value) =&amp;gt; Cookies.set(key, value, { expires: 7 }),
        removeItem: key =&amp;gt; Cookies.remove(key)
    }
    })
]
})
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;根据我的使用来说，如果是存储普通类型的数据，sessionStorage和localStorage可以直接存储，如果是存储对象与数组则需要使用JSON.stringify进行转换，转换为JSON字符串，在storage中存储，如果需要使用则需要通过JSON.parse解析，而通过这个插件，就不需要手动设置存储到storage中，也不需要使用JSON，而是插件将所有state的值以对象的形式存储到localStorage中的vuex为key的value中，通过读取value获取数据。&lt;/p&gt;
">vuex 数据持久化插件</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/zhuan-zai-na-xie-ni-zong-shi-ji-bu-zhu-dan-you-zong-shi-yao-yong-de-css/"" data-c="
          &lt;h2 id=&#34;一-设置input-的placeholder的字体样式&#34;&gt;一、设置input 的placeholder的字体样式&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;input::-webkit-input-placeholder {    /* Chrome/Opera/Safari */
    color: red;
}
input::-moz-placeholder { /* Firefox 19+ */  
    color: red;
}
input:-ms-input-placeholder { /* IE 10+ */
    color: red;
}
input:-moz-placeholder { /* Firefox 18- */
    color: red;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;设置input聚焦时的样式&#34;&gt;设置input聚焦时的样式&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;input:focus {   
  background-color: red;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;取消input的边框&#34;&gt;取消input的边框&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;border: none;
outline: none;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;二-隐藏滚动条或更改滚动条样式&#34;&gt;二、隐藏滚动条或更改滚动条样式&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;/*css主要部分的样式*//*定义滚动条宽高及背景，宽高分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar {
    width: 10px; /*对垂直流动条有效*/
    height: 10px; /*对水平流动条有效*/
}

/*定义滚动条的轨道颜色、内阴影及圆角*/
::-webkit-scrollbar-track{
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
    background-color: rosybrown;
    border-radius: 3px;
}

/*定义滑块颜色、内阴影及圆角*/
::-webkit-scrollbar-thumb{ 
    border-radius: 7px;
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
    background-color: #E8E8E8;
}

/*定义两端按钮的样式*/
::-webkit-scrollbar-button {
    background-color:cyan;
}

/*定义右下角汇合处的样式*/
::-webkit-scrollbar-corner {
    background:khaki;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;三-文字超出隐藏并显示省略号&#34;&gt;三、文字超出隐藏并显示省略号&lt;/h2&gt;
&lt;h3 id=&#34;单行一定要有宽度&#34;&gt;单行（一定要有宽度）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;width:200rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;多行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;word-break: break-all;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;四-控制div内的元素自动换行&#34;&gt;四、控制div内的元素自动换行&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;word-wrap: break-word;
word-break：break-all;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;五-纯css画三角形&#34;&gt;五、 纯css画三角形&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#demo {
    width: 0;
    height: 0;
    border-width: 20px;
    border-style: solid;
    border-color: transparent transparent red transparent;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;六-绝对定位元素居中水平和垂直方向&#34;&gt;六、 绝对定位元素居中（水平和垂直方向）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#demo {
    width: 200px;
    height: 200px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
    background-color: green;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;七-表格边框合并&#34;&gt;七、表格边框合并&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;table,tr,td{border: 1px solid #333;}
table{
  border-collapse: collapse;
}
&lt;/code&gt;&lt;/pre&gt;
">转载：那些你总是记不住但又总是要用的css</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/vuex-yu-dao-de-yi-ge-cuo-wu/"" data-c="
          &lt;p&gt;使用vuex的mutations时遇到的一个错误，找了一下没找到答案，换个方法就规避了这个错误，这个应该不算是错误，因为报错提示&lt;code&gt;handler: &amp;quot;Error: [vuex] expects string as the type, but found undefined.&amp;quot;&lt;/code&gt;是需要字符串，我这边传递的是对象，之前的使用中也是传递的字符串，所以错误应该是这个原因。&lt;br&gt;
错误代码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...mapMutations({
    setNewSong: &amp;quot;SET_NEWSONG&amp;quot;,
    }),

fn(){
    this.$store.commit(this.setNewSong(item));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;正常代码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...mapMutations([&amp;quot;SET_NEWSONG&amp;quot;]),
fn(){
    this.$store.commit(&amp;quot;SET_NEWSONG&amp;quot;, item);
}
&lt;/code&gt;&lt;/pre&gt;
">vuex遇到的一个错误</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-amis/"" data-c="
          &lt;h2 id=&#34;什么是-amis&#34;&gt;什么是 amis&lt;/h2&gt;
&lt;p&gt;amis 是一个低代码前端框架，它使用 JSON 配置来生成页面，可以减少页面开发工作量，极大提升效率。&lt;/p&gt;
&lt;h2 id=&#34;为什么要做-amis&#34;&gt;为什么要做 amis？&lt;/h2&gt;
&lt;p&gt;在经历了十几年的发展后，前端开发变得越来越复杂，门槛也越来越高，要使用当下流行的 UI 组件库，你必须懂 npm、webpack、react/vue，必须熟悉 ES6 语法，最好还了解状态管理，比如 Redux，如果没接触过函数式编程，光入门都很费劲，而入门之后会发现它还有巨大的 生态，相关的库有 2347 个，很多功能相似，挑选成本高。&lt;/p&gt;
&lt;p&gt;然而前端技术的发展不会停滞，等学完这些后可能会发现大家都用 Hooks 了、某个打包工具取代 Webpack 了……&lt;/p&gt;
&lt;h2 id=&#34;用-json-写页面有什么好处&#34;&gt;用 JSON 写页面有什么好处&lt;/h2&gt;
&lt;p&gt;为了实现用最简单方式来生成大部分页面，amis 的解决方案是基于 JSON 来配置，它的独特好处是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;不需要懂前端：在百度内部，大部分 amis 用户之前从来没写过前端页面，也不会 JavaScript，却能做出专业且复杂的后台界面，这是所有其他前端 UI 库都无法做到的；&lt;/li&gt;
&lt;li&gt;不受前端技术更新的影响：百度内部最老的 amis 页面是 4 年多前创建的，至今还在使用，而当年的 Angular/Vue/React 版本现在都废弃了，当年流行的 Gulp 也被 Webpack 取代了，如果这些页面不是用 amis，现在的维护成本会很高；&lt;/li&gt;
&lt;li&gt;享受 amis 的不断升级：amis 一直在提升细节交互体验，比如表格首行冻结、下拉框大数据下不卡顿等，之前的 JSON 配置完全不需要修改；&lt;/li&gt;
&lt;li&gt;可以 完全 使用 可视化页面编辑器 来制作页面：一般前端可视化编辑器只能用来做静态原型，而 amis 可视化编辑器做出的页面是可以直接上线的。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;##amis 的其它亮点&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;提供完整的界面解决方案：其它 UI 框架必须使用 JavaScript 来组装业务逻辑，而 amis 只需 JSON 配置就能完成完整功能开发，包括数据获取、表单提交及验证等功能，做出来的页面不需要经过二次开发就能直接上线；&lt;/li&gt;
&lt;li&gt;内置 100+ 种 UI 组件：包括其它 UI 框架都不会提供的富文本编辑器、条件组合等，能满足各种页面组件展现的需求，而且对于特殊的展现形式还可以通过 自定义组件 来扩充；&lt;/li&gt;
&lt;li&gt;容器支持无限级嵌套：可以通过组合来满足各种布局需求；&lt;/li&gt;
&lt;li&gt;经历了长时间的实战考验：amis 在百度内部得到了广泛使用，在 4 年多的时间里创建了 3 万+ 页面，从内容审核到机器管理，从数据分析到模型训练，amis 满足了各种各样的页面需求，最复杂的页面有超过 1 万行 JSON 配置。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;amis-不适合做什么&#34;&gt;amis 不适合做什么？&lt;/h2&gt;
&lt;p&gt;使用 JSON 有优点但也有明显缺点，在以下场合并不适合 amis：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;大量定制 UI：JSON 配置使得 amis 更适合做有大量常见 UI 组件的页面，但对于面向普通客户（toC）的页面，往往追求个性化的视觉效果，这种情况下用 amis 就不合适，实际上绝大部分前端 UI 组件库也都不适合，只能定制开发。&lt;/li&gt;
&lt;li&gt;极为复杂或特殊的交互：&lt;br&gt;
1. 有些复杂的前端功能，比如 可视化编辑器，其中有大量定制的拖拽操作，这种需要依赖原生            DOM 实现的功能无法使用 amis。&lt;br&gt;
2. 但对于某些交互固定的领域，比如图连线，amis 后续会有专门的组件来实现。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个系列也是好久没写，关键是之前把前端领域比较有影响力的种种写出来以后，就不知道该写些什么了，几天码云更新的这篇文章算是让我知道了该写什么，虽然以后可能用不到amis，但是了解一下也是好的，amis有两种使用方法，npm与JS SDK，其中npm适合在react项目中，sdk适合对前端或是react不了解的开发者，但是sdk的方式难以自定义组件，通过这些天做项目的经验，自定义组件在我看来还是相当重要的，所以这个只能在学了react后使用，官方文档上各个组件倒是不少，但是没有react的经验，也没法立即使用，码云上400+的star数说明这个项目目前还不是很好，可以留意一下。&lt;/p&gt;
">每天一个名词解释—amis</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/b-zhan-bo-fang-qi-de-yi-ge-xiao-bug/"" data-c="
          &lt;p&gt;其实这个bug已经有好几天了，但是迟迟没修让我不禁怀疑是不是只有我遇到了这个bug，前几天的时候是打开新视频，当音量大于50%的时候，不论怎么调节，只要不使音量&amp;lt;=50%都不显示音量图标，静音的情况没有测试，今晚使用发现当音量&amp;lt; 50%的时候，会出现跟之前上面一样的情况(切换到静音状态再调节就好了)，不知道是不是修了旧bug又有了新bug。&lt;/p&gt;
">B站播放器的一个小BUG</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/bo-fang-qi-jin-du-tiao-gai-jin/"" data-c="
          &lt;p&gt;因为不满意之前的进度条样式，所以决定更换进度条，在参考多个其他项目之后，我发现还是elementUI的进度条比较合适，所以就换成了elementUI的slider组件，因为组件默认的颜色是蓝色，所以这里使用样式穿透更改组件颜色以及组件的高度，宽度等显示效果。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.slider /deep/ .el-slider {
  margin: 2px 4px;
  .el-slider__runway {
    height: 4px;
    margin: 4px 0px;
    // border: 1px solid red;
    .el-slider__bar {
      background: #fa2800;
      height: 4px;
    }
    .el-slider__button-wrapper {
      top: -7px;
      height: 0;
      .el-slider__button {
        width: 12px;
        height: 12px;
        border: 2px solid #fa2800;
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样进度条就符合了我的要求，然后遇到了一个问题，因为使用的是elementUI的el-slider组件+我自己写的其他代码组合而成的Slider组件，这里就有着父子组件传值的问题，而$emit的方式还是会报错，或者我把props里面的value值赋给子组件定义的counter，然后给le-slider组件v-model绑定为counter，这样虽然不会报错但是会使父组件的监听播放时间改变进度条位置的效果无效，所以最后采取了对象的方式处理&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return{
    value: {},
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将要传给子组件的值设置为对象类型，然后在赋值的时候添加一个属性接收参数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; this.value.data =
        (this.$refs.audio.currentTime / this.$refs.audio.duration) * 100;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后在传递的时候将整个对象传递过去&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Slider
      @showCurrent=&amp;quot;changeCurrent&amp;quot;
      :value=&amp;quot;value&amp;quot;
      :duration=&amp;quot;duration&amp;quot;
      :songName=&amp;quot;songName&amp;quot;
      :currentTime=&amp;quot;currentTime&amp;quot;
    &amp;gt;&amp;lt;/Slider&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在子组件赋值时采用对象属性的方式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;el-slider @change=&amp;quot;changCurrent&amp;quot; :show-tooltip=&amp;quot;false&amp;quot; v-model=&amp;quot;value.data&amp;quot;&amp;gt;&amp;lt;/el-slider&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在它绑定的change事件上绑定方法，通过$emit的方式提交给父组件，&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;changCurrent() {
      this.$emit(&amp;quot;showCurrent&amp;quot;, this.value.data);
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将值传递过去，父组件接收以后再更改自己的value.data的值，再传递给子组件，子组件再更改自己进度条滑块的位置，完成操作。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;changeCurrent(data) {
      this.$refs.audio.currentTime = (data / 100) * (this.duration / 1000);
},
&lt;/code&gt;&lt;/pre&gt;
">播放器进度条改进</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/uniapp-sheng-tai-xia-de-ui-kuang-jia-uview/"" data-c="
          &lt;p&gt;项目名称：uView项目作者：亡灵叙曲开源许可协议：MIT项目地址：https://gitee.com/xuqu/uView项目简介uView UI，是 uni-app 生态优秀的UI框架，全面的组件和便捷的工具会让您信手拈来，如鱼得水。项目特性兼容安卓，iOS，微信小程序，H5，QQ小程序，百度小程序，支付宝小程序，头条小程序60+精选组件，功能丰富，多端兼容，让您快速集成，开箱即用众多贴心的JS利器，让您飞镖在手，召之即来，百步穿杨众多的常用页面和布局，让您专注逻辑，事半功倍详尽的文档支持，现代化的演示效果按需引入，精简打包体积&lt;/p&gt;
&lt;h2 id=&#34;项目截图&#34;&gt;项目截图&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1599202752683.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1599202765911.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;开发者说&#34;&gt;开发者说&lt;/h2&gt;
&lt;p&gt;uView 的目标是做成 uniapp 生态的标杆，自由且免费开源。对此，uView 有清晰且明确的计划安排，uView 将会全面兼容 nvue，适配暗黑模式，整合unicloud，加入更多组件和模板等。但是，一个人的力量是不够的：为了开源，理想和自由，您可以加入 uView 的研发工作组，我们一起并肩奋战。如果您是做 UI 开发的同学，uView 同样欢迎，因为 uView 需要内外兼修。如果您是个积极活跃的人，那么也欢迎您加入 uView 的QQ群成为管理员。所有加入 uView 贡献的同学，都会在官网声明，并且有自己的个人专属页。&lt;/p&gt;
&lt;p&gt;作者：码云 Gitee&lt;br&gt;
链接：https://zhuanlan.zhihu.com/p/215456248&lt;br&gt;
来源：知乎&lt;br&gt;
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。&lt;/p&gt;
&lt;p&gt;ps：我去官方文档看了下，组件功能很完善，文档也很详细，码云上才53(算上我)个star(不过码云上uniapp也才2.1K的star)，说到码云，最近知乎上看有几个大佬都在说码云，不知道是收了费还是单纯的觉得码云好用，就我个人而言，码云的使用体验还是不错的，毕竟访问速度上比github快多了，而且码云的开发者都是使用中文的，再配合在各个社区孜孜不倦的推荐开源项目的码云官方号，使用体验真的很好，就这10几天就看到了不少像是这个uView还有之前的一个chart组件一样的开源作品。&lt;/p&gt;
">uniapp生态下的UI框架—uView</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/sou-suo-zu-jian/"" data-c="
          &lt;p&gt;做到了搜索功能，因为之前没做过，在这里卡了一下，所以记录一下。&lt;br&gt;
一开始是打算做成网易云的样式的，就是input聚焦以后弹出弹出层，然后里面列出推荐关键词，如果有历史搜索记录也列出来，但是这样效果很平常，所以就换了一个样式，换成点击搜索图标，整个页面模糊，弹出层内显示一个搜索框，下面列出推荐关键词。&lt;br&gt;
先是实现背景模糊&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.cover {
  backdrop-filter: blur(10px);
  width: 100%;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
  background: rgba(255, 255, 255, 0.22);
  cursor: default;
  z-index: 9;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里不知道为什么，整个背景的cursor都是Pointer，所以后面为了显示的效果，我将在其之上的search部分的curcor都设置为了default。使用backdrop-filter属性让它呈现模糊的效果，fixed是为了定位它的位置，因为是要显示在上面的，所以把它的层级提高了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.top::after {
      content: &amp;quot;&amp;quot;;
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-image: url(&amp;quot;https://163musicloud.oss-cn-beijing.aliyuncs.com/backImage.jpg&amp;quot;);
      background-position: center;
      filter: blur(10px);
      z-index: -1;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里是为了达到搜索框背景部分模糊的效果，借鉴了《css揭秘》这本书中对于毛玻璃的用法，filter与backdrop-filter的区别在于backdrop-filte可以让你为一个元素后面区域添加图形效果（如模糊或颜色偏移）。 因为它适用于元素背后的所有元素，为了看到效果，必须使元素或其背景至少部分透明。而filter是出现毛玻璃效果，内容和背景都会模糊，为了不遮挡搜索框，所以这里的z-index层级需设置为负数。&lt;br&gt;
👆为css部分&lt;br&gt;
👇为js部分&lt;br&gt;
因为要实现点击除弹出层外任意位置关闭弹出层的效果，所以这里要用到event，而vue中使用event就需要使用$event，在文档的事件处理那一节也有写。&lt;br&gt;
在要触发事件的那一层添加点击事件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;cover&amp;quot; v-show=&amp;quot;isShow&amp;quot; @click=&amp;quot;closeMsg($event)&amp;quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;closeMsg(event) {
      let btn = document.querySelector(&amp;quot;.search&amp;quot;);
      if (btn) {
        if (!btn.contains(event.target)) {
          this.isShow = false;
        }
      }
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在事件里对它进行判断。&lt;br&gt;
这里之所以被卡了很久就是因为不知道$event，之前竟然没有用到过，看文档的时候也不够仔细。&lt;br&gt;
它的使用还有两个要注意的点&lt;br&gt;
注意两点&lt;br&gt;
1.不使用圆括号，event被自动当作实参传入&lt;br&gt;
2.使用圆括号，必须显式的传入event对象，如果不传入可能最终找到的是全局的window .event&lt;br&gt;
最后贴一下效果图&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1599038569224.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
">搜索组件</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/zhuan-zai-shou-ge-vue-3-zu-jian-ku-fa-bu/"" data-c="
          &lt;h2 id=&#34;强大阵容和背景&#34;&gt;强大阵容和背景&lt;/h2&gt;
&lt;p&gt;· 联合 vuejs member、antd member、社区大佬，共同打造&lt;br&gt;
· 阿里巴巴、蚂蚁金服倾力支持&lt;br&gt;
· nuxtjs 官方示例组件库&lt;br&gt;
· 万星 Github 项目，欢迎 Star&lt;br&gt;
· 没错，就是 Ant Design Vue 2.0&lt;/p&gt;
&lt;h2 id=&#34;支持-vite-typescript开发体验比德芙还要丝滑&#34;&gt;支持 Vite &amp;amp; TypeScript，开发体验比德芙还要丝滑&lt;/h2&gt;
&lt;p&gt;不对 Vite 做过多评价和解析了，总之这玩意真的有点吊，丝滑的程度不是抹点油就能达到的级别，研发提效nn%不是梦。&lt;/p&gt;
&lt;h2 id=&#34;更加易用&#34;&gt;更加易用&lt;/h2&gt;
&lt;p&gt;一直被吐槽，很少做改变，不得不说，我们一直站在自己的角度去思考，去设计 API，总认为我们提供的就是最好的。&lt;br&gt;
在重构 2.0 的时候，我们深刻的反思这个问题，我们期望给大家带来更加易用的组件库，将组件库当作一个真正的产品去打磨，而不是去秀技术。降低心智成本，快速开发项目，将作为接下来产品打磨的主要原则。&lt;br&gt;
同样对于文档使用手册也将作为接下来的主要发力点，目前已经做了一部分的优化。&lt;br&gt;
你不用再考虑 defaultValue、value 的区别；&lt;br&gt;
也不用在去学习 v-decorator 是个啥；&lt;br&gt;
也不用去学习 JSX；&lt;br&gt;
......&lt;/p&gt;
&lt;h2 id=&#34;破坏性更新&#34;&gt;破坏性更新&lt;/h2&gt;
&lt;p&gt;很遗憾的是，在更加易用的同时，2.0 会有少许破坏性更新，一个原因是历史包袱问题，另一个原因是 Vue3 的改动调整。&lt;br&gt;
历史包袱：&lt;br&gt;
1、1.x 版本的作用域插槽参数是支持多参数的，因为在模板语法中是无法支持多参数的，Vue 最开始也并没有想到会有多参数的场景，因为组件库的底层是使用的render函数，是可以使用多参数的，所以在1.x版本就支持了多参数，但是对于模版开发中，多参数就会变得不是很友好。&lt;br&gt;
2、1.x 版本的一共提供了两个表单组件(Form、FormModel)，对于 Form 我们参考了 React 版本的表单实现方式，是通过上下文进行强制刷新，在 Vue 3 中如果还是这种方式，将无法享受到 patchFlag 带来的性能优化，而且它也带来了一定的心智成本，所以在 2.0 中，我们将 Form、FormModel 进行了合并，将 Form 强大的功能，和 FormModel 易用的特征结合，形成了新版的 Form。&lt;br&gt;
Vue 3 的改动：&lt;br&gt;
1、双向绑定 v-model 和 .sync 合并&lt;br&gt;
2、组件参数扁平化，如&lt;code&gt;{ props: {type: &#39;xxx&#39;}&lt;/code&gt;, on:&lt;code&gt;{click: this.handleClick}}&lt;/code&gt;改成&lt;code&gt;{ type: &#39;xxx&#39;, onClick: this.handleClick }&lt;/code&gt; 这个涉及组件并不多，改动成本并不大，详细可见下方说明。&lt;/p&gt;
&lt;h2 id=&#34;20-主要变化&#34;&gt;2.0 主要变化&lt;/h2&gt;
&lt;h3 id=&#34;设计规范调整&#34;&gt;设计规范调整&lt;/h3&gt;
&lt;p&gt;· 行高从 1.5(21px) 调整为 1.5715(22px)。&lt;br&gt;
· 基础圆角调整，由4px 改为 2px。&lt;br&gt;
· 分割线颜色明度降低，由 #E8E8E8 改为 #F0F0F0。&lt;br&gt;
· Table 默认背景颜色从透明修改为白色。&lt;/p&gt;
&lt;h3 id=&#34;兼容性调整&#34;&gt;兼容性调整&lt;/h3&gt;
&lt;p&gt;· IE 最低支持版本为 IE 11。&lt;br&gt;
· Vue 最低支持版本为 Vue 3.0。&lt;/p&gt;
&lt;h3 id=&#34;调整的-api&#34;&gt;调整的 API&lt;/h3&gt;
&lt;p&gt;移除了 LocaleProvider，请使用 ConfigProvider 替代。&lt;br&gt;
移除了 Tag 的 afterClose 属性。&lt;br&gt;
合并了 FormModel、Form，详见下方的 Form 重构部分。&lt;br&gt;
tabIndex、maxLength、readOnly、autoComplete、autoFocus 更改为全小写。&lt;br&gt;
为了在 template 语法中更友好的使用插槽，所有涉及到 xxxRender, renderXxxx 的均改成单参数，涉及到 itemRender、renderItem、customRender、dropdownRender、dateCellRender、dateFullCellRender、monthCellRender、monthFullCellRender、renderTabBar。&lt;br&gt;
所有配置 scopedSlots 的地方统一改成 slots。&lt;br&gt;
&lt;code&gt;{ on, props, attrs, ... }&lt;/code&gt;配置进行扁平化处理，如&lt;code&gt;{ props: {type: &#39;xxx&#39;}&lt;/code&gt;, on: &lt;code&gt;{click: this.handleClick}}&lt;/code&gt;改成&lt;code&gt;{ type: &#39;xxx&#39;, onClick: this.handleClick }&lt;/code&gt;, 涉及相关字段：okButtonProps、cancelButtonProps。&lt;br&gt;
xxx.sync 改成 v-model:xxx&lt;br&gt;
v-model 更改成 v-model:xxx，具体涉及组件：&lt;br&gt;
v-model 改成 v-model:checked 的组件有: CheckableTag、Checkbox、Switch&lt;br&gt;
v-model 改成 v-model:value 的组件有: Radio、Mentions、CheckboxGroup、Rate、DatePicker&lt;br&gt;
v-model 改成 v-model:visible 的组件有: Tag、Popconfirm、Popove、Tooltip、Moda、Dropdown&lt;br&gt;
v-model 改成 v-model:activeKey 的组件有: Collaps、Tabs&lt;br&gt;
v-model 改成 v-model:current 的组件有: Steps&lt;br&gt;
v-model 改成 v-model:selectedKeys 的组件有: Menu&lt;/p&gt;
&lt;h3 id=&#34;图标升级&#34;&gt;图标升级&lt;/h3&gt;
&lt;p&gt;在 ant-design-vue@1.2.0 中，我们引入了 svg 图标（为何使用 svg 图标？）。使用了字符串命名的图标 API 无法做到按需加载，因而全量引入了 svg 图标文件，这大大增加了打包产物的尺寸。在 2.0 中，我们调整了图标的使用 API 从而支持 tree shaking，减少默认包体积约 150 KB(Gzipped)。&lt;br&gt;
旧版 Icon 使用方式将被废弃：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;a-icon type=&amp;quot;smile&amp;quot; /&amp;gt; &amp;lt;a-button icon=&amp;quot;smile&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;2.0 中会采用按需引入的方式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;smile-outlined /&amp;gt;
  &amp;lt;a-button&amp;gt;
    &amp;lt;template v-slot:icon&amp;gt;&amp;lt;smile-outlined /&amp;gt;&amp;lt;/template&amp;gt;
  &amp;lt;/a-button&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
import SmileOutlined from &#39;@ant-design/icons/SmileOutlined&#39;;
export default {
  components: {
    SmileOutlined
  }
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;组件重构&lt;br&gt;
在 1.x 中我们提供了 Form、FormModel 两个表单组件，原有的 Form 组件使用 v-decorator 进行数据绑定，在 Vue2 中我们通过上下文进行强制更新组件，但是在 Vue3 中，由于引入 patchFlag 等优化方式，强制刷新会破坏 patchFlag 带来的性能优势。所以在 2.0 版本中我们将 Form、FormModel 进行合并，保留了 FormModel 的使用方式，丰富了相关功能，并改名成 Form。&lt;br&gt;
涉及改动：&lt;br&gt;
Form 新增 scrollToFirstError,name,validateTrigger 属性，新增 finish、finishFailed 事件，新增 scrollToField 方法。&lt;br&gt;
Form.Item 新增 validateFirst, validateTrigger, 废弃 prop 属性，使用 name 替换。&lt;br&gt;
嵌套字段路径使用数组，过去版本我们通过 . 代表嵌套路径（诸如 user.name 来代表&lt;code&gt;{ user: { name: &#39;&#39; } }）&lt;/code&gt;。然而在一些后台系统中，变量名中也会带上 .。这造成用户需要额外的代码进行转化，因而新版中，嵌套路径通过数组来表示以避免错误的处理行为（如 [&#39;user&#39;, &#39;name&#39;]）。&lt;br&gt;
validateFields 不再支持 callback。validateFields 会返回 Promise 对象，因而你可以通过 async/await 或者 then/catch 来执行对应的错误处理。不再需要判断 errors 是否为空：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// v1
validateFields((err, value) =&amp;gt; {
  if (!err) {
    // Do something with value
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;改成&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// v2
validateFields().then(values =&amp;gt; {
  // Do something with value
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;作者：zeka&lt;br&gt;
链接：https://juejin.im/post/6867515263672123399&lt;br&gt;
来源：掘金&lt;/p&gt;
">转载：首个 Vue 3 组件库发布</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/vue-yang-shi-chuan-tou/"" data-c="
          &lt;p&gt;今天写demo的搜索框，因为使用的是ElementUI的input组件，所以需要更改默认样式，但是直接在style内定义样式无效，需要使用样式穿透。&lt;br&gt;
正常的样式穿透(stylus适用)：&amp;gt;&amp;gt;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.search-wrap &amp;gt;&amp;gt;&amp;gt; .el-input__inner {
  background: #a82828;
  width: 220px;
  height: 24px;
  border-radius: 20px;
  color: #c77373;
  border: none;
  margin-left: 20px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;sass/less中的样式穿透：/deep/&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.search-wrap /deep/ .el-input__inner {
  background: #a82828;
  width: 220px;
  height: 24px;
  border-radius: 20px;
  color: #c77373;
  border: none;
  margin-left: 20px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为我的项目使用了less，所以使用第二种做样式穿透。&lt;/p&gt;
">Vue样式穿透</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/vue-tong-lu-you-tiao-zhuan-chuan-can/"" data-c="
          &lt;p&gt;之前好像没遇到过这种情况，都是不同路由的传参跳转，比较简单，今天遇到了同路由传参的情况，一开始是打算通过之前的带路由地址和参数的方式跳转，然后重新使用created中的方法，但是并不行，中间学到了一个方法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err =&amp;gt; err)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以用来屏蔽掉路由重复的报错，虽然报错没了，但是也没跳转啊，不是很明白这个的具体用处，我路由就是为了切换页面，同路径的传参路由就是为了切换数据，用这个虽然屏蔽了同页面路由的报错，但是也没能切换数据啊，意义不明。最后找到了3种方法，第一：使用watch监听路由变化，手动更新数据；第二：使用router-view；第三：使用provide-inject。最终选择了第一种watch监听。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;watch: {
    $route(n, o) {
      if (n.fullPath !== o.fullPath) {
        //监听路由参数是否变化
        location.reload(); //强制刷新页面
      }
    },
  },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一开始是监听到路由参数改变直接强制刷新页面，问题在于用户体验太差，后面改成了刷新各个函数的调用，这样就不会有屏幕刷新的问题，可惜事与愿违，video.js组件一个生命周期内只能被声明一次，所以最后还是只能强制刷新页面。&lt;/p&gt;
">Vue同路由跳转传参</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/shi-pin-bo-fang-qi-cha-jian-de-shi-yong/"" data-c="
          &lt;p&gt;其实看的好几个demo都是用的原生的Video标签，但是我感觉不是很好看，就去网上找了几个，分别有vue-video和vue-video-player，还有个HTML5的video.js，vue-video已经三年多没更新了，所以直接pass，然后就是vue-video-player与video.js对比，原本我是打算使用vue-video-player的，毕竟github上3.3k的star数，但是发现使用过程中过于繁琐，而且样式也不是很好，声音没法做到改变大小，只能是开启或静音，这样还要额外写一个切换声音的功能，并且它的倍速播放功能也不是很有必要，而且我在github上看到它有29k的star，所以最后选择了video.js。&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;$ npm install video.js&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;引入&#34;&gt;引入&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import Video from &#39;video.js&#39; 
import &#39;video.js/dist/video-js.css&#39;

Vue.prototype.$video = Video  //挂载到原型上
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;在项目中使用&#34;&gt;在项目中使用&lt;/h2&gt;
&lt;h3 id=&#34;html部分&#34;&gt;HTML部分&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt; &amp;lt;video id=&amp;quot;myVideo&amp;quot; class=&amp;quot;video-js&amp;quot;&amp;gt;
      &amp;lt;source
        src=&amp;quot;http://vodkgeyttp8.vod.126.net/cloudmusic/
        5805/core/a70e/407418faf42d67b7f0a095fc137dbc
        8e.mp4?wsSecret=49d2d403360b1ce82d0c12432a
        4c395e&amp;amp;wsTime=1598668903&amp;quot;
        type=&amp;quot;video/mp4&amp;quot;
      /&amp;gt;
    &amp;lt;/video&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;初始化视频方法&#34;&gt;初始化视频方法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;methods: {
    initVideo() {
      //初始化视频方法
      let myPlayer = this.$video(myVideo, {
        //确定播放器是否具有用户可以与之交互的控件。
        //没有控件，启动视频播放的唯一方法是使用autoplay属性或通过Player API。
        controls: true,
        //自动播放属性,muted:静音播放
        autoplay: &amp;quot;muted&amp;quot;,
        //建议浏览器是否应在&amp;lt;video&amp;gt;加载元素后立即开始下载视频数据。
        preload: &amp;quot;auto&amp;quot;,
        //设置视频播放器的显示宽度
        width: &amp;quot;800px&amp;quot;,
        //设置视频播放器的显示高度
        height: &amp;quot;400px&amp;quot;,
      });
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;在挂载钩子内执行&#34;&gt;在挂载钩子内执行&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;mounted() { 
        this.initVideo();
    },
&lt;/code&gt;&lt;/pre&gt;
">视频播放器插件的使用</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/vue-zhong-shi-yong-momentjs-ge-shi-hua-shi-jian-chuo/"" data-c="
          &lt;p&gt;今天在做网易云的demo时，因为要展示创建时间，而API给的数据是时间戳，所以要对时间戳进行格式化，网上发现了一个较moment.js的插件，可以非常方便的处理时间戳，记录一下。&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;npm install moment --save&lt;/code&gt;|&lt;code&gt;cnpm install moment --save&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;引入&#34;&gt;引入&lt;/h2&gt;
&lt;p&gt;在main中全局引入，并且定义全局的时间过滤器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 定义全局时间戳过滤器
Vue.filter(&amp;quot;formatDate&amp;quot;, function(value) {
  return Moment(value).format(&amp;quot;YYYY-MM-DD&amp;quot;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;按照以上设置可以返回YYYY-MM-DD格式的日期，也可以按照一下方式设置&lt;br&gt;
日期格式化&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;moment().format(&#39;MMMM Do YYYY, h:mm:ss a&#39;); // 四月 16日 2019, 12:24:48 中午
moment().format(&#39;dddd&#39;);                    // 星期二
moment().format(&amp;quot;MMM Do YY&amp;quot;);               // 4月 16日 19
moment().format(&#39;YYYY [escaped] YYYY&#39;);     // 2019 escaped 2019
moment().format();                          // 2019-04-16T12:24:48+08:00
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;相对时间&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;moment(&amp;quot;20111031&amp;quot;, &amp;quot;YYYYMMDD&amp;quot;).fromNow(); // 7 年前
moment(&amp;quot;20120620&amp;quot;, &amp;quot;YYYYMMDD&amp;quot;).fromNow(); // 7 年前
moment().startOf(&#39;day&#39;).fromNow();        // 12 小时前
moment().endOf(&#39;day&#39;).fromNow();          // 12 小时内
moment().startOf(&#39;hour&#39;).fromNow();       // 28 分钟前
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;日历时间&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;moment().subtract(10, &#39;days&#39;).calendar(); // 2019年4月6日
moment().subtract(6, &#39;days&#39;).calendar();  // 上周三中午12点28
moment().subtract(3, &#39;days&#39;).calendar();  // 上周六中午12点28
moment().subtract(1, &#39;days&#39;).calendar();  // 昨天中午12点28分
moment().calendar();                      // 今天中午12点28分
moment().add(1, &#39;days&#39;).calendar();       // 明天中午12点28分
moment().add(3, &#39;days&#39;).calendar();       // 本周五中午12点28
moment().add(10, &#39;days&#39;).calendar();      // 2019年4月26日
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;多语言支持&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;moment().format(&#39;L&#39;);    // 2019-04-16
moment().format(&#39;l&#39;);    // 2019-04-16
moment().format(&#39;LL&#39;);   // 2019年4月16日
moment().format(&#39;ll&#39;);   // 2019年4月16日
moment().format(&#39;LLL&#39;);  // 2019年4月16日中午12点28分
moment().format(&#39;lll&#39;);  // 2019年4月16日中午12点28分
moment().format(&#39;LLLL&#39;); // 2019年4月16日星期二中午12点28分
moment().format(&#39;llll&#39;); // 2019年4月16日星期二中午12点28分
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;文档地址：http://momentjs.cn/&lt;br&gt;
不过使用的时候也有一些问题，我如果想要其他方式处理图片，比如想要返回demo中歌单的创建日期为多长时间以前，就要新设置一个全局的filter，并且命名不能和其余的处理函数相同，然后在需要的地方引用，我认为这种较为麻烦，应该有别的更简单的方法，集合在一个函数内完成，不过我试着像该函数传值并没有成功。&lt;/p&gt;
">vue中使用moment.js格式化时间戳</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/fang-wang-yi-yun-demo-day4/"" data-c="
          &lt;h2 id=&#34;设置路由懒加载&#34;&gt;设置路由懒加载&lt;/h2&gt;
&lt;p&gt;先放一段定义用法&lt;br&gt;
vue中的懒加载和按需加载&lt;br&gt;
懒加载&lt;/p&gt;
&lt;p&gt;（1）定义：懒加载也叫延迟加载，即在需要的时候进行加载，随用随载。&lt;/p&gt;
&lt;p&gt;（2）异步加载的三种表示方法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1.  resolve =&amp;gt; require([URL], resolve),支持性好
2.  () =&amp;gt; system.import(URL) , webpack2官网上已经声明将逐渐废除,不推荐使用 
3.  () =&amp;gt; import(URL), webpack2官网推荐使用,属于es7范畴,需要配合babel的syntax-dynamic- 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;import插件使用。&lt;br&gt;
（3）vue中懒加载的流程：&lt;br&gt;
（4）Vue中懒加载的各种使用地方：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;路由懒加载：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;export default new Router({
  routes:[
    {
     path: &#39;/my&#39;,
     name: &#39;my&#39;,
      //懒加载
     component: resolve =&amp;gt; require([&#39;../page/my/my.vue&#39;], resolve),
    },
  ]
})
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;组件懒加载：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;components: {
  historyTab:resolve =&amp;gt; {
  require([&#39;../../component/historyTab/historyTab.vue&#39;],resolve)
  },   
},
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;全局懒加载：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;Vue.component(&#39;mideaHeader&#39;, () =&amp;gt; {
System.import(&#39;./component/header/header.vue&#39;)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我自己的路由懒加载&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const routes = [
  {
    path: &amp;quot;/main&amp;quot;,
    component: (resolve) =&amp;gt; require([&amp;quot;@/components/main&amp;quot;], resolve),
  },
  {
    path: &amp;quot;/ranklist&amp;quot;,
    component: (resolve) =&amp;gt; require([&amp;quot;@/components/main/Ranklist&amp;quot;], resolve),
  },
  {
    path: &amp;quot;/recommendlist&amp;quot;,
    component: (resolve) =&amp;gt; require([&amp;quot;@/components/recommend-list&amp;quot;], resolve),
  },
  {
    path: &amp;quot;/newestmusic&amp;quot;,
    component: (resolve) =&amp;gt; require([&amp;quot;@/components/newest-music&amp;quot;], resolve),
  },
  {
    path: &amp;quot;/mv&amp;quot;,
    component: (resolve) =&amp;gt; require([&amp;quot;@/components/mv&amp;quot;], resolve),
  },
];
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;设置图片懒加载&#34;&gt;设置图片懒加载&lt;/h2&gt;
&lt;p&gt;cnpm引入：cnpm i vue-lazyload --save&lt;br&gt;
main.js中引入&lt;code&gt;import VueLazyload from &#39;vue-lazyload&#39;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Vue.use(VueLazyload, {
  preLoad: 1.3,
  error: &amp;quot;dist/error.png&amp;quot;,
  loading: &amp;quot;dist/loading.gif&amp;quot;,
  attempt: 1,
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在页面中使用，替换原本的:src为v-lazy&lt;br&gt;
&lt;code&gt;&amp;lt;img v-lazy=&amp;quot;item.album.blurPicUrl&amp;quot; alt /&amp;gt;&lt;/code&gt;&lt;br&gt;
不过在使用了路由和图片懒加载后还是有卡顿的现象，我看到网上说的优化方法里，还有按需引入和减少图片，减少图片引用应该是不行了，按需引入可以考虑，毕竟项目使用了两个UI组件库，而且基本只使用了图标功能，可以考虑按需引入，之前使用阿里ICON的时候没注意还有个复制svg的选项，有这个项目里都不需要引入UI框架了。不过这个应该也算是对网络资源的请求吧？&lt;/p&gt;
">仿网易云demo—day4</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/ge-chong-shi-yong-ji-qiao/"" data-c="
          &lt;p&gt;文字截断&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;white-space: nowrap;/*保证文本内容不会自动换行，如果多余的内容会在水平方向撑破单元格*/ 
overflow: hidden; /*隐藏超出单元格的部分*/
text-overflow: ellipsis; /*将被隐藏的那部分用省略号代替*/


white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;👆单行👇多行 &lt;code&gt;-webkit-line-clamp: 2;&lt;/code&gt;切换行数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  white-space: pre-wrap;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;去除input边框&lt;br&gt;
&lt;code&gt;&amp;lt;input type=&amp;quot;text&amp;quot; &amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; input {
        border: 0;  // 去除未选中状态边框
        outline: none; // 去除选中状态边框
        background-color: rgba(0, 0, 0, 0);// 透明背景
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改滚动条样式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.main::-webkit-scrollbar {
  width: 8px;
  height: 1px;
}
/*滚动条滑块*/
.main::-webkit-scrollbar-thumb {
  border-radius: 8px;
  background: #ccc;
}
/*滚动条轨道*/
.main::-webkit-scrollbar-track {
  border-radius: 10px;
  background: #fff;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;字母换行&lt;br&gt;
&lt;code&gt;word-break: break-all;&lt;/code&gt;&lt;br&gt;
去除图片下空隙&lt;br&gt;
&lt;code&gt;display:block&lt;/code&gt;&lt;br&gt;
设置模糊&lt;br&gt;
&lt;code&gt;filter: blur(16px);&lt;/code&gt;&lt;/p&gt;
">各种实用技巧</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/fang-wang-yi-yun-xiang-mu-de-bo-fang-qi-zu-jian/"" data-c="
          &lt;p&gt;目前为止，这个项目中比较费时的就是播放器组件了，因为要尽量还原网易云的样式，所以不能使用HTML5的Audio的默认样式，需要自己写，这样的话就需要自己写播放/暂停按钮、上一首/下一首、显示歌曲总时长以及歌曲当前播放时长、歌曲播放进度条、声音大小进度条、播放模式等等功能，这里写篇文章记录一下，方便以后查找。&lt;/p&gt;
&lt;p&gt;controls ：用来控制Audio播放器的显示与隐藏&lt;br&gt;
volume ：当前音量&lt;br&gt;
currentTime ：以秒为单位返回播放时长&lt;br&gt;
loop ：设置为循环播放或查询是否为循环播放&lt;br&gt;
autoplay ：自动播放&lt;br&gt;
autobuffer ：媒体文件播放前是否进行缓冲加载，如果设置了autoplay，则忽略此特性&lt;br&gt;
duration ：获取媒体文件的播放时长，以秒为单位，如果无法获取，则为 NaN&lt;/p&gt;
&lt;p&gt;暂且先完成播放、暂停、总时长与播放时长、音量切换、进度切换功能&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;audio ref=&amp;quot;audio&amp;quot; :src=&amp;quot;songUrl&amp;quot;&amp;gt;&amp;lt;/audio&amp;gt;&lt;/code&gt;&lt;br&gt;
通过ref获取audio&lt;br&gt;
&lt;code&gt;&amp;lt;div @click=&amp;quot;play&amp;quot; class=&amp;quot;play-btn&amp;quot;&amp;gt; &amp;lt;Icon v-show=&amp;quot;playMusic&amp;quot; size=&amp;quot;28&amp;quot; color=&amp;quot;white&amp;quot; type=&amp;quot;ios-pause&amp;quot; /&amp;gt; &amp;lt;Icon v-show=&amp;quot;pauseMusic&amp;quot; size=&amp;quot;28&amp;quot; color=&amp;quot;white&amp;quot; type=&amp;quot;ios-play&amp;quot; /&amp;gt; &amp;lt;/div&amp;gt;&lt;/code&gt;给播放/暂停按钮绑定事件&lt;br&gt;
&lt;code&gt;isStore: &amp;quot;false&amp;quot;,&lt;/code&gt;通过isStore判断播放与暂停状态&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-play()&#34;&gt;      if (this.isStore) {
        this.$refs.audio.play();
      } else {
        this.$refs.audio.pause();
      }
      this.isStore = !this.isStore;
      this.pauseMusic = !this.pauseMusic;
      this.playMusic = !this.playMusic;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;切换事件，其实命名为toogle更好&lt;br&gt;
获取播放时长并转为 00 - 00 形式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;durationTime() {
      var minute = this.$refs.audio.duration / 60;
      var minutes = parseInt(minute);
      if (minutes &amp;lt; 10) {
        minutes = &amp;quot;0&amp;quot; + minutes;
      }
      var second = this.$refs.audio.duration % 60;
      var seconds = Math.round(second);
      if (seconds &amp;lt; 10) {
        seconds = &amp;quot;0&amp;quot; + seconds;
      }
      this.duration = `${parseInt(minute)}:${parseInt(second)}`;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获取当前播放时长 也转换为 00 - 00 形式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;currendTime() {
      var minute = this.$refs.audio.currentTime / 60;
      var minutes = parseInt(minute);
      if (minutes &amp;lt; 10) {
        minutes = &amp;quot;0&amp;quot; + minutes;
      }
      var second = this.$refs.audio.currentTime % 60;
      var seconds = Math.round(second);
      if (seconds &amp;lt; 10) {
        seconds = &amp;quot;0&amp;quot; + seconds;
      }
      this.current = `${minutes}:${seconds}`;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置音量大小&lt;br&gt;
&lt;code&gt;voiceDown: true, voiceUp: false,&lt;/code&gt;通过这两个控制音量开关&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Icon v-show=&amp;quot;voiceDown&amp;quot; @click=&amp;quot;volumDown&amp;quot; size=&amp;quot;20&amp;quot; type=&amp;quot;md-volume-up&amp;quot; /&amp;gt;
&amp;lt;Icon v-show=&amp;quot;voiceUp&amp;quot; @click=&amp;quot;volumUp&amp;quot; size=&amp;quot;20&amp;quot; type=&amp;quot;md-volume-off&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过v-show来切换状态，添加点击事件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;volumDown() {
      this.lastVoice = this.$refs.audio.volume;
      this.$refs.audio.volume = 0;
      this.voiceDown = false;
      this.voiceUp = true;
      this.voiceLength = this.$refs.voiceOpt.style.width;
      this.$refs.voiceOpt.style.width = 0;
    },
    volumUp() {
      this.$refs.audio.volume = this.lastVoice;
      this.$refs.voiceOpt.style.width = this.voiceLength;
      this.voiceUp = false;
      this.voiceDown = true;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;两个点击事件分别控制状态的切换以及保存静音前音量控制条的进度&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div @click=&amp;quot;changeVoice&amp;quot; class=&amp;quot;voice-bbb&amp;quot;&amp;gt;
        &amp;lt;div class=&amp;quot;voice-background&amp;quot;&amp;gt;
          &amp;lt;div ref=&amp;quot;voiceOpt&amp;quot; class=&amp;quot;voice-front&amp;quot; :style=&amp;quot;{width: operatewidth + &#39;px&#39;}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再给最外层的div添加点击事件，因为内部第一层div用作背景，所以需要和进度条同高度，最内层div用于展示进度条，所以设置的比较细，如果在这一层加事件，则必须改变自身高度，不然点击较为不易。在最内层绑定了动态属性，用于通过点击事件控制div宽度，达到根据点击位置切换宽度的效果。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;changeVoice(val) {
      var length = val.clientX - this.$refs.voiceOpt.offsetLeft;
      this.$refs.audio.volume = length / 130;
      this.operatewidth = 130 - (130 - length);
      console.log(this.$refs.audio.volume);
      this.voiceUp = false;
      this.voiceDown = true;
    },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为采用百分比无法计算，所以进度条采用固定宽度的方式，根据当前进度条和背景宽度的比值求出当前音量大小并赋给audio的volume属性，来达到控制音量的目的。&lt;/p&gt;
">仿网易云项目的播放器组件</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-dart/"" data-c="
          &lt;p&gt;都在说API，API到底是什么？对于很多非IT人士而言，API ≈ 听不懂。&lt;/p&gt;
&lt;p&gt;其实日常生活中，我们有很多类似API的场景，比如：&lt;br&gt;
电脑需要调用手机里面的信息，这时候你会拿一根数据线将电脑手机连接起来，电脑和手机上连接数据线的接口就是传说中的API接口。&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1598266112897.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;但比喻到底是比喻并非本质-想要真正理解api还得老老实实去理解api的使用场景&#34;&gt;但比喻到底是比喻，并非本质。想要真正理解API，还得老老实实去理解API的使用场景。&lt;/h3&gt;
&lt;p&gt;先来一段按惯例放上、但可跳过不看的百科介绍：&lt;br&gt;
API，英文全称Application Programming Interface，翻译为“应用程序编程接口”。是一些预先定义的函数，目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力，而又无需访问源码，或理解内部工作机制的细节。——百度百科&lt;br&gt;
我们不妨把API的诞生过程用一个小故事展示出来：&lt;br&gt;
研发人员A开发了软件A，研发人员B正在研发软件B。有一天，研发人员B想要调用软件A的部分功能来用，但是他又不想从头看一遍软件A的源码和功能实现过程，怎么办呢？研发人员A想了一个好主意：我把软件A里你需要的功能打包好，写成一个函数；你按照我说的流程，把这个函数放在软件B里，就能直接用我的功能了！其中，API就是研发人员A说的那个函数。&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1598266195467.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
那么API在实际工作中是如何使用的呢？这里借一下我们的客户案例（此处感谢国银通宝的大数据总监郑斌先生友情给我们提供素材）：&lt;br&gt;
大家所在的企业应该用过一些办公软件，比如在国银通宝，他们的办公软件主要是用于管理仓库货物的ERP软件，但是这个ERP系统却不支持手机上报销。怎么办？了解的朋友知道，简道云是一个支持企业搭建个性化应用的平台，国银通宝可以在简道云上直接搭建一个报销管理系统。但总不可能报销系统在简道云上，货物管理在ERP系统上。此时API接口就派上了大用场，通过简道云开放的API接口，国银通宝把简道云和ERP系统对接起来。相当于国银通宝同时用了两个软件的功能，但数据又是彻底打通的。&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1598266222441.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
到这里，大家对API的含义应该有所了解，但对接API的过程对于非IT人员而言，却不是那么简单，因为其中涉及到服务器搭建等问题，所以一般我们都比较希望使用API的企业有信息部门。不过近期我们发现了一个国外软件zapier，通过这个整合Slack、Trello、Excel、Gmail等1000+知名软件的平台上，对接API的过程被极大程度地简化了。同样的例子，如果说API是电脑和手机上的接口，那么zapier就相当于一根标准的安卓数据线。&lt;br&gt;
通过zapier可以将很多常见的软件对接起来，产生新的功能。如果你有一个开通了API接口的简道云账号，那么就能将简道云和slack、trello这些知名软件对接起来。比如以下就是一个将简道云和Gmail通过zapier对接的场景：&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1598266248380.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
原本的表单使用模式：用户打开外链，在表单中录入数据，提交完事。&lt;/p&gt;
&lt;p&gt;现在对接了Gmail功能：用户打开外链，在表单中录入数据和邮箱地址，提交后，自己邮箱将会收到一封邮件。（如上图）&lt;/p&gt;
&lt;p&gt;作者：简道云&lt;br&gt;
链接：https://www.zhihu.com/question/38594466/answer/487039892&lt;/p&gt;
">每天一个名词解释—Api</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/qu-chu-input-bian-kuang-yi-ji-xuan-zhong-shi-bian-kuang-mo-ren-yang-shi/"" data-c="
          &lt;p&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;text&amp;quot; &amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; input {
        border: 0;  // 去除未选中状态边框
        outline: none; // 去除选中状态边框
        background-color: rgba(0, 0, 0, 0);// 透明背景
    }
&lt;/code&gt;&lt;/pre&gt;
">去除input边框以及选中时边框 默认样式</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/xiu-gai-gun-dong-tiao/"" data-c="
          &lt;pre&gt;&lt;code&gt;.main::-webkit-scrollbar {
  width: 8px;
  height: 1px;
}
/*滚动条滑块*/
.main::-webkit-scrollbar-thumb {
  border-radius: 8px;
  background: #ccc;
}
/*滚动条轨道*/
.main::-webkit-scrollbar-track {
  border-radius: 10px;
  background: #fff;
}
&lt;/code&gt;&lt;/pre&gt;
">修改滚动条</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-deno/"" data-c="
          &lt;h1 id=&#34;介绍&#34;&gt;介绍&lt;/h1&gt;
&lt;p&gt;Deno 是一个 JavaScript/TypeScript 的运行时，默认使用安全环境执行代码，有着卓越的开发体验。&lt;/p&gt;
&lt;p&gt;Deno 建立在 V8、Rust 和 Tokio 的基础上。&lt;/p&gt;
&lt;h2 id=&#34;功能亮点&#34;&gt;功能亮点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;默认安全。外部代码没有文件系统、网络、环境的访问权限，除非显式开启。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持开箱即用的 TypeScript 的环境。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;只分发一个独立的可执行文件 (deno)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;有着内建的工具箱，比如一个依赖信息查看器 (deno info) 和一个代码格式化工具 (deno fmt)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;有一组经过审计的 标准模块，保证能在 Deno 上工作。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;脚本代码能被打包为一个单独的 JavaScript 文件。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;目标&#34;&gt;目标&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;只分发一个独立的可执行文件 (deno)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;默认安全。外部代码没有文件系统、网络、环境的访问权限，除非显式开启。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器兼容：完全用 JavaScript 编写且不使用全局Deno命名空间(或功能测试)的程序是 Deno 程序的子集，应该能够直接在现代浏览器中运行而无需更改。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;提供内置工具来提升开发体验，比如单元测试、代码格式化、代码检查。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不把 V8 的概念泄露到用户空间。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;能够高效地提供 HTTP 服务&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;与-nodejs-的比较&#34;&gt;与 Node.js 的比较&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Deno 不使用 npm，而是使用 URL 或文件路径引用模块。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deno 在模块解析算法中不使用 package.json。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deno 中的所有异步操作返回 promise，因此 Deno 提供与 Node 不同的 API。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deno 需要显式指定文件、网络和环境权限。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当未捕获的错误发生时，Deno 总是会异常退出。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用 ES 模块，不支持 require()。第三方模块通过 URL 导入。&lt;br&gt;
&lt;code&gt;import * as log from &amp;quot;https://deno.land/std@$STD_VERSION/log/mod.ts&amp;quot;;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
">每天一个名词解释—Deno</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/fang-wang-yi-yun-demo-day3/"" data-c="
          &lt;p&gt;还是换做客户端了，网页端的界面实在是不好看，而且布局也不够灵活，最终还是换成做客户端，还是先创建项目，引入各种依赖，鉴于首页的跑马灯使用elementUI能直接符合效果，就又引入了elementUI&lt;img src=&#34;https://jujuul.github.io//post-images/1598087573125.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;其实关于封装还不能说是完全弄懂，只能是按照网上的模仿一下，教程里还用到了拦截器，我不知道有什么使用场景，所以就先注释掉了，以我对于封装的理解就是定义各个功能的方法，然后暴露出去，另一个文件调用，然后把不同文件暴露的功能拼接到一起，再暴露给其他页面调用。&lt;/p&gt;
">仿网易云demo—day3</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/fang-wang-yi-yun-demo-day2/"" data-c="
          &lt;h1 id=&#34;悲报&#34;&gt;悲报&lt;/h1&gt;
&lt;p&gt;为了解决一个图片无法加载的问题，在网上随便搜了一些文章，安装了css-loader和vue-loader，然后就爆炸了，样式全无，网上搜不到任何有用的信息，诡异的事情发生了，竟然有一篇今天下午3点42的文章，也提到了这个问题，不过他的解决办法我并不能看懂，只能B计划了。😭😭😭&lt;/p&gt;
&lt;p&gt;我吐了，明明之前删了3词node_modules文件夹了，都没用，结果第四次就成功了，难道是因为之前删除都是通过vscode的原因？&lt;/p&gt;
&lt;p&gt;反正正常了，那就继续吧，不过这网页端实在是没什么好做的啊，布局也是用的float，还有很多雪碧图，稍微做一下我还是去做一下桌面端的样式吧，或者考虑学下electron用它做个桌面端程序。&lt;/p&gt;
">仿网易云demo—day2</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/tiobe-2020-nian-8-yue-bian-cheng-yu-yan-pai-xing/"" data-c="
          &lt;p&gt;本月 TIOBE 排行榜总体变化不大。R 语言自上个月迎来史无前例的高光时刻后，本月依旧保持增长势头，并有望成为 2020 年的年度编程语言。&lt;/p&gt;
&lt;p&gt;除此之外，Go、Swift、SQL 三种语言在第 10 名这个位置的角逐也十分有趣。其中 Swift 在本月下降 2 个名次，从第 10 名降到了第 12 名。SQL 将其取而代之，成为第 10 名。同样值得注意的是，Groovy 重新进入了排行榜的前 20名，并且 Hack 在第 44 位，也成功进入了前 50 名。&lt;/p&gt;
&lt;h3 id=&#34;编程语言排行榜-top-20-榜单&#34;&gt;编程语言排行榜 TOP 20 榜单：&lt;/h3&gt;
&lt;figure data-type=&#34;image&#34; tabindex=&#34;1&#34;&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1597993815737.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/figure&gt;
&lt;h3 id=&#34;前-10-名编程语言长期走势图&#34;&gt;前 10 名编程语言长期走势图：&lt;/h3&gt;
&lt;figure data-type=&#34;image&#34; tabindex=&#34;2&#34;&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1597993834133.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/figure&gt;
&lt;h3 id=&#34;以下是-21-50-编程语言排名&#34;&gt;以下是 21-50 编程语言排名：&lt;/h3&gt;
&lt;figure data-type=&#34;image&#34; tabindex=&#34;3&#34;&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1597993848553.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/figure&gt;
&lt;!-- more --&gt;
&lt;p&gt;原文链接：https://www.hangge.com/blog/cache/detail_2989.html&lt;/p&gt;
">TIOBE - 2020年8月编程语言排行</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-swift/"" data-c="
          &lt;h2 id=&#34;swift介绍&#34;&gt;Swift介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Swift是苹果于2014年WWDC（苹果开发者大会）发布的新开发语言，可与Objective-C共同运行于MAC OS和iOS平台，用于搭建基于苹果平台的应用程序。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Swift 使用自动引用计数（Automatic Reference Counting, ARC）来简化内存管理&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Swift Foundation框架可无缝对接现有的 Cocoa 框架，并且兼容 Objective-C 代码，支持面向过程编程和面向对象编程，Swift也是一门类型安全的语言。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Swift中范型是用来使代码能安全工作，可以在函数数据和普通数据类型中使用，例如类、结构体或枚举。范型可以解决代码复用的问题&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;swift优点&#34;&gt;Swift优点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简洁的语法，性能较好&lt;br&gt;
swift语言比OC精简，整个项目中丢掉了.h头文件，以及头文件的引入。性能是Objective-C的1.3倍&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;报错精准&lt;br&gt;
报错的时候直接显示报错行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;定义变量简单&lt;br&gt;
定义变量不用区分整型，浮点型等等，变量使用var，常量使用let。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可视化互动效果&lt;br&gt;
开发工具带来了Xcode Playgrounds功能，该功能提供强大的互动效果，能让Swift源代码在撰写过程中实时显示出其运行结果。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;函数式编程的支持（Map、FlatMap、Filter、Reduce等函数方法）&lt;br&gt;
Swift 语言本身提供了对函数式编程的支持；&lt;br&gt;
Objc 本身是不支持的，通过引入 ReactiveCocoa 这个库才可支持。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;swift缺点&#34;&gt;Swift缺点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;推广度还不全面，资源少&lt;br&gt;
很多大公司，以及一些老的项目，仍然使用OC语言进行开发。当遇到一些问题的时候，解决问题的方案很少，网上的资源也很稀缺。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;还不稳定&lt;br&gt;
从swift2.0到swift3.0再到现在的swift4.0区别很大，每次升级都会有几十甚至上百个错误提示，难免急出一身冷汗。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第三方库的支持不够多&lt;br&gt;
现在swift版本的第三方库是非常稀有的，有时需要导入OC版本的第三方来进行混合开发，而有的·兼容性·并不好，而且使项目变大，运行速度也会变慢。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;App体积变大&lt;br&gt;
使用 Swift 后， App 体积大概增加 5-8 M左右，对体积大小敏感的慎用。（体积变大的原因是因为 Swift 还在变化，所以 Apple 没有在 iOS 系统里放入 Swift 的运行库，反而是每个 App 里都要包含其对应的 Swift 运行库。）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;上线方式改变&lt;br&gt;
不能使用application Loader上传包文件，会提示你丢失了swift support files，只能使用xcode直接上传。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;官网地址：https://www.apple.com.cn/swift/&lt;/p&gt;
">每天一个名词解释—Swift</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/wo-zi-yong-de-yi-xie-vscode-cha-jian-fen-xiang/"" data-c="
          &lt;p&gt;今天逛思否的时候，发现一个推荐vscode插件的文章，里面推荐了8个插件，竟然有6个是我没用过的，也借这个机会，整理一下自己用的插件&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Beautify&lt;br&gt;
听名字就能猜到功能了，整理代码用的，500W+的下载量足以证明其强大。&lt;/li&gt;
&lt;li&gt;Auto Close Tag&lt;br&gt;
也是个听名字就能猜到功能的，320W+下载量。&lt;/li&gt;
&lt;li&gt;Auto Rename Tag&lt;br&gt;
跟上面的是同一个作者开发的，可以在更改标签名的时候做到更改一边而两边都被更改的效果，340W+。&lt;/li&gt;
&lt;li&gt;Bracket Pair Colorizer&lt;br&gt;
我个人强力推荐，没完没了的函数中看代码真的是一种折磨，有了它就能清晰的看出(){}[]是否闭合，再也不用担心少个)}]了，340W+。&lt;/li&gt;
&lt;li&gt;Chinese (Simplified) Language Pack for Visual Studio Code&lt;br&gt;
简中语言包，600W+足以证明，另外我去看了下繁中版，也有270W+，中文开发者真的多啊。&lt;/li&gt;
&lt;li&gt;Code Runner&lt;br&gt;
可以直接运行其他语言，使Vs Code成为一个IDE?我是之前毕设项目后端使用PHP才安装的这个插件，不过好像没什么用，话说我在Vscode上配置过java和python的运行环境，效果都不是很理想啊，编辑器和IDE还是有很大区别的啊，466W+。&lt;/li&gt;
&lt;li&gt;CSS Peek&lt;br&gt;
今天被安利的插件，鼠标悬停在类名或者ID上能直接看到CSS规则，100W+。&lt;/li&gt;
&lt;li&gt;Debugger for Chrome&lt;br&gt;
就是在vscode中启动chrome控制台，需要一些比较繁琐的配置，我只是安装了，但从没用过，620W+。&lt;/li&gt;
&lt;li&gt;indent-rainbow&lt;br&gt;
可以和前面第四个联用，这个是在缩进的地方用彩色填充，也是起到一个很好的查看代码的效果,100W+。&lt;/li&gt;
&lt;li&gt;JavaScript (ES6) code snippets&lt;br&gt;
今天受的安利之一，可以生成ES6的代码片段，原来VSCODE不可以的吗？我只生成过VUE的代码片段，但是vue不是使用的ES6语法吗？不是很理解，380W+。&lt;/li&gt;
&lt;li&gt;Live Server&lt;br&gt;
好像可以用来做服务器？而且是自动刷新(热插拔)的那种？也是没有使用过，服务器都是自己用nodejs搭的，原来还有这么方便的，67W+。&lt;/li&gt;
&lt;li&gt;open in browser&lt;br&gt;
在浏览器中打开，还可以选择浏览器，非常实用的功能，220W+。&lt;/li&gt;
&lt;li&gt;Prettier - Code formatter&lt;br&gt;
也是一个代码格式的插件，我记得使用时有要求选择alt+thift+f做出选择，我选了Beautify，我原本以为是冲突的，但今天看了很多介绍用它们两个整理格式的，好像并不冲突？有时间去配置一下，790W+。&lt;/li&gt;
&lt;li&gt;Quokka.js&lt;br&gt;
今天的安利之一，直接放图吧&lt;img src=&#34;https://jujuul.github.io//post-images/1597983693060.gif&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;76W+。&lt;/li&gt;
&lt;li&gt;REST Client&lt;br&gt;
REST Client 扩展工具允许你发送 HTTP 请求并直接在 VSCode 中查看响应。再也不需要使用外部应用程序向服务器发送 HTTP 请求，还没用，不过看了动图我觉得可以试试&lt;img src=&#34;https://jujuul.github.io//post-images/1597983840428.gif&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;100W+。&lt;/li&gt;
&lt;li&gt;TabNine&lt;br&gt;
一个代码补全工具，基于人工智能，自动补全时会给出每个候选项的概率，并且按照概率大小进行排序，此外，会给出候选项的来源及地址，这样更加方便查询和阅读，31W+。&lt;/li&gt;
&lt;li&gt;Vetur&lt;br&gt;
vue开发必装，之前不知道干嘛的，今天看了一下，是对于vue文件中的语法检查、语法高亮还有自动补全，530W+。&lt;/li&gt;
&lt;li&gt;ESLint&lt;br&gt;
JS代码检测工具，配合之前的几个代码检测，写出的代码将无敌，可惜不会写，配置比较繁琐，1000W+。&lt;/li&gt;
&lt;/ol&gt;
">我自用的一些vscode插件分享</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-kuai-ying-yong/"" data-c="
          &lt;h2 id=&#34;背景介绍&#34;&gt;背景介绍&lt;/h2&gt;
&lt;p&gt;快应用是一种新的应用形态，以往的手机端应用主要有两种方式：网页、原生应用；网页无需安装，却体验不是很好；原生应用体验流畅，却需要从应用商店下载安装，难以一步直达用户；快应用的出现，就是希望能够让用户无需下载安装，并且还能流畅的体验应用内容。&lt;/p&gt;
&lt;p&gt;为了达到上面的目标，快应用建立一种新的语言开发规范，同时提供一系列的开发套件辅助支持。简单来说，开发者主要利用前端知识与技能，以及对应的IDE，手机设备就可以做原型的开发。快应用使用前端技术栈开发，原生渲染，同时具备H5与原生应用的双重优点，开发者使用的前端技术栈资料多，学习成本低。&lt;/p&gt;
&lt;p&gt;2018年3月份，由小米，OPPO，VIVO，华为等10家国内主流厂商成立了快应用联盟，从技术规范层面做了统一，并保证了开发者开发的快应用可以直接在所有的联盟内厂商的手机设备上运行。&lt;/p&gt;
&lt;p&gt;快应用框架深度集成进各手机厂商的手机操作系统中，可以在操作系统层面形成用户需求与应用服务的无缝连接，很多只用在原生应用中才能使用的功能，在快应用中可以很方便的实现，享受原生应用体验，同时不用担心分发留存等问题，资源消耗也比较少。&lt;/p&gt;
&lt;p&gt;对于每台手机设备，应用可以从多个系统入口，引用用户体验产品。比如：全局搜索、负一屏、浏览器搜索等。&lt;/p&gt;
&lt;p&gt;下面，我们全面介绍一下快应用的开发流程。&lt;/p&gt;
&lt;h2 id=&#34;入口场景&#34;&gt;入口场景&lt;/h2&gt;
&lt;p&gt;快应用的部分场景入口列举如下：&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597937182347.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;比如全局搜索&#34;&gt;比如：全局搜索&lt;/h3&gt;
&lt;figure data-type=&#34;image&#34; tabindex=&#34;1&#34;&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1597937210145.gif&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/figure&gt;
&lt;h2 id=&#34;参与流程&#34;&gt;参与流程&lt;/h2&gt;
&lt;p&gt;开发者参与快应用开发，主要分为以下几个步骤:&lt;/p&gt;
&lt;p&gt;快应用官网注册&lt;br&gt;
完善资料&lt;br&gt;
绑定厂商开发者账号(至少一家)&lt;br&gt;
完成以上三部，快应用开发者就可以提交快应用。&lt;/p&gt;
&lt;h3 id=&#34;整体参与流程如图所示&#34;&gt;整体参与流程如图所示:&lt;/h3&gt;
&lt;figure data-type=&#34;image&#34; tabindex=&#34;2&#34;&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1597937254951.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/figure&gt;
&lt;h2 id=&#34;如何开发&#34;&gt;如何开发&lt;/h2&gt;
&lt;p&gt;快应用采用前端技术栈，运行可开发效率高，学习成本低，代码可复用&lt;/p&gt;
&lt;p&gt;快应用开发需要基本基础的前端知识，如 标签， 样式， js脚本&lt;/p&gt;
&lt;p&gt;快应用使用 MVVM的设计模式进行开发，开发者无需直接操作DOM节点的增删，利用数据驱动的方式完成节点更新。&lt;/p&gt;
&lt;p&gt;当前标准的开发规范与Vue的开发方式相近，后期可能开放并接入其它的DSL开发方式，以符合开发者的开发习惯。&lt;/p&gt;
&lt;h2 id=&#34;开发过程&#34;&gt;开发过程&lt;/h2&gt;
&lt;p&gt;进行快应用开发，整体过程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;准备开发工具&lt;br&gt;
快应用开发需要准备PC/笔记本，厂商手机，内网环境或者手机可连接电脑&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开发调试&lt;br&gt;
开发调试过程:&lt;/p&gt;
&lt;p&gt;1.通过命令行工具，或者IDE安装并运行快应用&lt;br&gt;
2.了解命令行工具生成的项目结构，编写项目代码&lt;br&gt;
3.通过 toolkit，chrome devtools 进行调试&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;提交上传&lt;br&gt;
完成代码相关工作，我们就可以提交上传快应用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
">每天一个名词解释—快应用</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/fang-wang-yi-yun-demo-day1/"" data-c="
          &lt;p&gt;一直想找个vue项目做，不知道做什么好，在B站知乎看到了同一条推送，做的网易云音乐，我之前也有做网易云音乐的打算，但是苦于没有后端数据，看了推送的项目发现原来有开源的api接口，赞美互联网。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;github：https://github.com/Binaryify/NeteaseCloudMusicApi&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597890809917.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
一共一百多条，应该是涵盖了所有功能，话不多说，开搞。&lt;br&gt;
如何使用我就不赘述了，这个链接里都有https://www.jianshu.com/p/a375dd77b502&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597890883922.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
可以看到已经跑起来了&lt;br&gt;
接下来就是考虑做网易云音乐程序页面还是网页端页面了，虽然我更喜欢程序的页面，不过为了不跟视频冲突，还是决定做网页端了。&lt;br&gt;
接下来是划分页面功能，我借鉴的例子是这样组装页面的&lt;img src=&#34;https://jujuul.github.io//post-images/1597892249770.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
考虑到这个项目可能还要做线上展示，所以还是打算放到服务器上了，刚好之前申请的域名也下来了，直接通过域名调用接口吧(话说也是够倒霉的，遇上阿里云升级，之前做的仿美团项目都已经忘了怎么做了快)&lt;br&gt;
在项目的根目录新建一个vue.config.js的文件，然后配置proxy代理&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597910160351.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
接着在需要请求的页面发起axios请求&lt;img src=&#34;https://jujuul.github.io//post-images/1597910235597.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
">仿网易云demo—day1</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/http-huan-cun/"" data-c="
          &lt;p&gt;&lt;strong&gt;文章转载于：https://www.jianshu.com/p/227cee9c8d15&lt;/strong&gt;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;前端缓存可分为两大类：http缓存和浏览器缓存。今天要讨论的就是http缓存&lt;img src=&#34;https://jujuul.github.io//post-images/1597825032998.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;什么是http缓存&#34;&gt;什么是HTTP缓存 ？&lt;/h2&gt;
&lt;p&gt;http缓存指的是: 当客户端向服务器请求资源时，会先抵达浏览器缓存，如果浏览器有“要请求资源”的副本，就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。&lt;/p&gt;
&lt;p&gt;常见的http缓存只能缓存get请求响应的资源，对于其他类型的响应则无能为力，所以后续说的请求缓存都是指GET请求。&lt;/p&gt;
&lt;p&gt;http缓存都是从第二次请求开始的。第一次请求资源时，服务器返回资源，并在respone header头中回传资源的缓存参数；第二次请求时，浏览器判断这些请求参数，命中强缓存就直接200，否则就把请求参数加到request header头中传给服务器，看是否命中协商缓存，命中则返回304，否则服务器会返回新的资源。&lt;/p&gt;
&lt;h2 id=&#34;http缓存的分类&#34;&gt;http缓存的分类：&lt;/h2&gt;
&lt;p&gt;根据是否需要重新向服务器发起请求来分类，可分为(强制缓存，协商缓存) 根据是否可以被单个或者多个用户使用来分类，可分为(私有缓存，共享缓存) 强制缓存如果生效，不需要再和服务器发生交互，而协商缓存不管是否生效，都需要与服务端发生交互。下面是强制缓存和协商缓存的一些对比：&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597825112453.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;强制缓存&#34;&gt;强制缓存&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;强缓存是利用Expires或者Cache-Control这两个http response header实现的，它们都用来表示资源在客户端缓存的有效期。&lt;/strong&gt;&lt;br&gt;
Expires是HTTP 1.0提出的一个表示资源过期时间的header，它描述的是一个绝对时间，由服务器返回，用GMT格式的字符串表示，如：Expires:Thu, 31 Dec 2037 23:55:55 GMT，包含了Expires头标签的文件，就说明浏览器对于该文件缓存具有非常大的控制权。&lt;/p&gt;
&lt;p&gt;例如，一个文件的Expires值是2020年的1月1日，那么就代表，在2020年1月1日之前，浏览器都可以直接使用该文件的本地缓存文件，而不必去服务器再次请求该文件，哪怕服务器文件发生了变化。所以，Expires是优化中最理想的情况，因为它根本不会产生请求，所以后端也就无需考虑查询快慢。&lt;/p&gt;
&lt;p&gt;强制缓存在缓存数据未失效的情况下（即Cache-Control的max-age没有过期或者Expires的缓存时间没有过期），那么就会直接使用浏览器的缓存数据，不会再向服务器发送任何请求。强制缓存生效时，http状态码为200。&lt;/p&gt;
&lt;p&gt;这种方式页面的加载速度是最快的，性能也是很好的，但是在这期间，如果服务器端的资源修改了，页面上是拿不到的，因为它不会再向服务器发请求了。&lt;/p&gt;
&lt;p&gt;这种情况就是我们在开发种经常遇到的，比如你修改了页面上的某个样式，在页面上刷新了但没有生效，因为走的是强缓存，所以Ctrl + F5一顿操作之后就好了。 跟强制缓存相关的header头属性有（Pragma/Cache-Control/Expires）&lt;/p&gt;
&lt;h2 id=&#34;协商缓存&#34;&gt;协商缓存&lt;/h2&gt;
&lt;p&gt;当第一次请求时服务器返回的响应头中没有Cache-Control和Expires或者Cache-Control和Expires过期还或者它的属性设置为no-cache时(即不走强缓存)，那么浏览器第二次请求时就会与服务器进行协商，与服务器端对比判断资源是否进行了修改更新。如果服务器端的资源没有修改，那么就会返回304状态码，告诉浏览器可以使用缓存中的数据，这样就减少了服务器的数据传输压力。如果数据有更新就会返回200状态码，服务器就会返回更新后的资源并且将缓存信息一起返回。跟协商缓存相关的header头属性有（ETag/If-Not-Match 、Last-Modified/If-Modified-Since）请求头和响应头需要成对出现&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597825700506.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
协商缓存的执行流程是这样的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当浏览器第一次向服务器发送请求时，会在响应头中返回协商缓存的头属性：ETag和Last-Modified,其中ETag返回的是一个hash值，Last-Modified返回的是GMT格式的最后修改时间。&lt;/li&gt;
&lt;li&gt;然后浏览器在第二次发送请求的时候，会在请求头中带上与ETag对应的If-Not-Match，其值就是响应头中返回的ETag的值，Last-Modified对应的If-Modified-Since。&lt;/li&gt;
&lt;li&gt;服务器在接收到这两个参数后会做比较，如果返回的是304状态码，则说明请求的资源没有修改，浏览器可以直接在缓存中取数据，否则，服务器会直接返回数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;为什么要使用http缓存&#34;&gt;为什么要使用HTTP缓存 ？&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;减少了冗余的数据传输，节省了网费。&lt;/li&gt;
&lt;li&gt;缓解了服务器的压力， 大大提高了网站的性能&lt;/li&gt;
&lt;li&gt;加快了客户端加载网页的速度&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;如何使用http缓存&#34;&gt;如何使用HTTP缓存 ？&lt;/h2&gt;
&lt;p&gt;一般需要缓存的资源有html页面和其他静态资源：&lt;br&gt;
1、html页面缓存的设置主要是在&lt;head&gt;标签中嵌入&lt;meta&gt;标签，这种方式只对页面有效，对页面上的资源无效&lt;br&gt;
1.1、html页面禁用缓存的设置如下：&lt;/p&gt;
&lt;meta http-equiv=&#34;pragma&#34; content=&#34;no-cache&#34;&gt;
// 仅有IE浏览器才识别的标签，不一定会在请求字段加上Pragma，但的确会让当前页面每次都发新请求
&lt;meta http-equiv=&#34;cache-control&#34; content=&#34;no-cache&#34;&gt;
// 其他主流浏览器识别的标签
&lt;meta http-equiv=&#34;expires&#34; content=&#34;0&#34;&gt;
// 仅有IE浏览器才识别的标签，该方式仅仅作为知会IE缓存时间的标记，你并不能在请求或响应报文中找到Expires字段
&lt;p&gt;1.2、html设置缓存如下：&lt;br&gt;
&lt;code&gt;&amp;lt;meta http-equiv=&amp;quot;Cache-Control&amp;quot; content=&amp;quot;max-age=7200&amp;quot; /&amp;gt;&lt;/code&gt;&lt;br&gt;
// 其他主流浏览器识别的标签&lt;br&gt;
&lt;code&gt;&amp;lt;meta http-equiv=&amp;quot;Expires&amp;quot; content=&amp;quot;Mon, 20 Aug 2018 23:00:00 GMT&amp;quot; /&amp;gt;&lt;/code&gt;&lt;br&gt;
// 仅有IE浏览器才识别的标签&lt;/p&gt;
&lt;p&gt;2 静态资源的缓存一般是在web服务器上配置的，常用的web服务器有：nginx、apache。具体的配置这里不做详细介绍，大家自行查阅。&lt;/p&gt;
&lt;p&gt;3 不想使用缓存的几种方式：&lt;br&gt;
3.1 Ctrl + F5强制刷新，都会直接向服务器提取数据。&lt;br&gt;
3.2 按F5刷新或浏览器的刷新按钮，默认加上Cache-Control：max-age=0，即会走协商缓存。&lt;br&gt;
3.2 在IE浏览器下不想使用缓存的做法：打开IE，点击工具栏上的工具-&amp;gt;Internet选项-&amp;gt;常规-&amp;gt;浏览历史记录 设置. 选择“从不”，然后保存。最后点击“删除”把Internet临时文件都删掉 （IE缓存的文件就是Internet临时文件）。&lt;br&gt;
3.3 还有就是上面1、2中禁用缓存的做法&lt;br&gt;
3.4 对于其他浏览器也都有清除缓存的办法&lt;/p&gt;
&lt;h2 id=&#34;http缓存的几个注意点&#34;&gt;HTTP缓存的几个注意点？&lt;/h2&gt;
&lt;p&gt;1 强缓存情况下，只要缓存还没过期，就会直接从缓存中取数据，就算服务器端有数据变化，也不会从服务器端获取了，这样就无法获取到修改后的数据。决解的办法有：在修改后的资源加上随机数,确保不会从缓存中取。&lt;/p&gt;
&lt;p&gt;例如：&lt;br&gt;
http://www.kimshare.club/kim/common.css?v=22324432&lt;br&gt;
http://www.kimshare.club/kim/common.2312331.css&lt;/p&gt;
&lt;p&gt;2 尽量减少304的请求，因为我们知道，协商缓存每次都会与后台服务器进行交互，所以性能上不是很好。从性能上来看尽量多使用强缓存。&lt;/p&gt;
&lt;p&gt;3 在Firefox浏览器下，使用Cache-Control: no-cache 是不生效的，其识别的是no-store。这样能达到其他浏览器使用Cache-Control: no-cache的效果。所以为了兼容Firefox浏览器，经常会写成Cache-Control: no-cache，no-store。&lt;/p&gt;
&lt;p&gt;4 与缓存相关的几个header属性有：Vary、Date/Age。&lt;br&gt;
Vary：&lt;br&gt;
vary本身是“变化”的意思，而在http报文中更趋于是“vary from”（与。。。不同）的含义，它表示服务端会以什么基准字段来区分、筛选缓存版本。&lt;br&gt;
在服务端有着这么一个地址，如果是IE用户则返回针对IE开发的内容，否则返回另一个主流浏览器版本的内容。&lt;br&gt;
格式：Vary: User-Agent&lt;br&gt;
知会代理服务器需要以 User-Agent 这个请求首部字段来区别缓存版本，防止传递给客户端的缓存不正确。&lt;/p&gt;
&lt;p&gt;Date/Age：&lt;br&gt;
响应报文中的 Date 和 Age 字段：区分其收到的资源是否命中了代理服务器的缓存。&lt;br&gt;
Date 理所当然是原服务器发送该资源响应报文的时间（GMT格式），如果你发现 Date 的时间与“当前时间”差别较大，或者连续F5刷新发现 Date 的值都没变化，则说明你当前请求是命中了代理服务器的缓存。&lt;br&gt;
Age 也是响应报文中的首部字段，它表示该文件在代理服务器中存在的时间（秒），如文件被修改或替换，Age会重新由0开始累计。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;1 对于强制缓存，服务器通知浏览器一个缓存时间，在缓存时间内，下次请求，直接用缓存，不在时间内，执行协商缓存策略。&lt;br&gt;
2 对于协商缓存，将缓存信息中的Etag和Last-Modified通过请求发送给服务器，由服务器校验，返回304状态码时，浏览器直接使用缓存。&lt;/p&gt;
&lt;p&gt;再次感谢：kimshare   https://www.jianshu.com/p/227cee9c8d15&lt;br&gt;
最后，附图一张&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597824906056.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
图源运维社区：https://www.unixhot.com/page/cache&lt;/p&gt;
">HTTP缓存</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-webpack/"" data-c="
          &lt;h1 id=&#34;概念&#34;&gt;概念&lt;/h1&gt;
&lt;p&gt;本质上，webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时，它会递归地构建一个依赖关系图(dependency graph)，其中包含应用程序需要的每个模块，然后将所有这些模块打包成一个或多个 bundle。&lt;/p&gt;
&lt;p&gt;webpack是一个打包工具，可以将项目中用到的各种文件按照一定的规则集合起来。在这个过程中可以进行诸如图片压缩、ES6语法转ES5语法、TypeScript转JavaScript等等操作。&lt;/p&gt;
&lt;h2 id=&#34;与gulpgrunt等打包工具有什么区别&#34;&gt;与gulp/grunt等打包工具有什么区别？&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;gulp 是自动化构建工具，可以配合各种插件做 js 压缩、css 压缩、less 编译、代码检查等，替代手工实现自动化工作&lt;/code&gt;&lt;br&gt;
1 构建工具&lt;br&gt;
2 自动化&lt;br&gt;
3 提高效率用&lt;/p&gt;
&lt;p&gt;&lt;code&gt;webpack是文件打包工具，可以把项目的各种 js、css文件等打包合并成一个或多个文件，主要用于模块化方案，预编译模块的方案&lt;/code&gt;&lt;br&gt;
1 打包工具&lt;br&gt;
2 模块化识别&lt;br&gt;
3 编译模块化代码方案用&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;说到webpack，那还要说到 seajs / requirejs / browserify。这四个都是JS模块化的方案。其中 seajs / require 是一种类型，webpack/browserify是另一种类型。&lt;/p&gt;
&lt;p&gt;seajs / require : 是一种在线&amp;quot;编译&amp;quot; 模块的方案，相当于在页面上加载一个CMD/AMD解释器。这样浏览器就认识了 define、exports、module 这些东西。也就实现了模块化。&lt;br&gt;
webpack/browserify : 是一个预编译模块的方案，相比于上面 ，这个方案更加智能。没用过 browserify，这里以webpack为例。首先，它是预编译的，不需要在浏览器中加载解释器。另外，你在本地直接写JS，不管是 AMD / CMD / ES6 风格的模块化，它都能认识，并且编译成浏览器认识的JS。&lt;br&gt;
  总结，Gulp是一个工具，而webpack是模块化方案。Gulp 也可以配置seajs、requirejs 甚至 webpack 的插件。&lt;/p&gt;
">每天一个名词解释—webpack</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-dan-ye-ying-yong/"" data-c="
          &lt;h1 id=&#34;什么是单页应用&#34;&gt;什么是单页应用&lt;/h1&gt;
&lt;p&gt;在早期的 Web 应用中，前端的作用很弱，业务逻辑和数据处理都在后端，后端给前端返回一个 HTML 页面，前端只负责展示。在这种模式下，单个 HTML 页面被当做一个功能原件，表单提交，超链接跳转都可以用来重新请求新的 HTML 页面，从而达到给用户展示新的页面的目的。在这种方式中，你可以感觉到页面总是在不停的刷新，一个点击可能都需要等待很久，这是因为，当页面变化时，所有资源都需要重新请求。这些问题导致了用户体验不佳，也浪费了资源。单页应用便很好的解决了这些问题。&lt;/p&gt;
&lt;h2 id=&#34;概念&#34;&gt;概念&lt;/h2&gt;
&lt;p&gt;什么是单页应用呢？单页应用的全称是 single-page application，简称 SPA，它是一种网站应用的模型，它可以动态重写当前的页面来与用户交互，而不需要重新加载整个页面。单页应用的流畅性让 Web 应用更像桌面端或 Native 应用了。相对于传统的 Web 应用，单页应用做到了前后端分离，后端只负责处理数据提供接口，页面逻辑和页面渲染都交给了前端。前端发展到现在，单页应用的使用已经很广泛，目前时兴的 React、Vue、Angular 等前端框架均采用了 SPA 原则。单页应用意味着前端掌握了主动权，也让前端代码更复杂和庞大，模块化、组件化以及架构设计都变得越来越重要。&lt;br&gt;
来体验一下单页应用吧，打开你的 Gmail，点击左侧的导航栏，在开发者工具的 Network 中可以看到资源是按需加载的，此时页面也并没有刷新，观察 Elements 栏下的 HTML，你会发现整个 HTML 的大框架是不变的，页面改变时，或者说路由改变时，DOM 树只是改变它需要改变的部分，也就是动态改变。&lt;/p&gt;
&lt;h2 id=&#34;工作原理&#34;&gt;工作原理&lt;/h2&gt;
&lt;p&gt;SPA 的一个重要实现就是改变路由时，页面不刷新。实现这个功能，通常有两种方式：使用 window.history 对象或 location.hash。&lt;/p&gt;
&lt;h3 id=&#34;history-对象&#34;&gt;history 对象&lt;/h3&gt;
&lt;p&gt;window.history 包含了浏览器的历史信息，它有以下几种常用方法：&lt;br&gt;
• history.back()：与在浏览器点击后退按钮相同；&lt;br&gt;
• history.forward()：与在浏览器中点击按钮向前相同；&lt;br&gt;
• history.go(n)：接受一个整数作为参数，移动到该整数指定的页面，比如 go(1) 相当于 forward()，go(-1) 相当于 back()，go(0) 相当于刷新当前页面。&lt;br&gt;
HTML5 对 history 对象新增了 pushState() 和 replaceState() 方法，这两个方法可以往历史栈中添加数据，给用户的感觉就是浏览器的 url 改变了，但是页面并没有重新加载。pushState() 是在浏览记录中添加一个新记录，replaceState() 则是修改当前的浏览器记录，这是二者的细微差别，使用时参数的字段和含义都是一样的。&lt;br&gt;
&lt;code&gt;window.history.pushState(state, title, url)&lt;/code&gt;&lt;br&gt;
• state 是状态对象，可以用 history.state 读取；&lt;br&gt;
• title 表示新页面的标题，但是现在的所有浏览器都会忽略这个字段，所以可以传 null；&lt;br&gt;
• url 是新页面的地址，必须是和当前页面在同一个域。&lt;/p&gt;
&lt;p&gt;当用户点击浏览器上的前进和后退按钮时，或者调用上述 window.history 的 back、forward 和 go 方法，就会触发 popstate 事件。该事件只针对同一个文档，如果浏览历史的切换导致加载了不同的文档，popstate 事件将不会被触发。popstate 事件回调函数的参数中的 state 属性指向 pushState() 和 replaceState() 方法为当前页面提供的状态，也就是 pushState() 和 replaceState() 方法使用时传的第一个参数 state。&lt;/p&gt;
&lt;p&gt;我们可以通过 pushState() 简单模拟一下浏览器的路由改变且不刷新页面。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;a class=&amp;quot;spa&amp;quot;&amp;gt;spa1.html&amp;lt;/a&amp;gt;
&amp;lt;a class=&amp;quot;spa&amp;quot;&amp;gt;spa2.html&amp;lt;/a&amp;gt;

&amp;lt;button onclick=&amp;quot;goBack()&amp;quot;&amp;gt;back&amp;lt;/button&amp;gt;
&amp;lt;button onclick=&amp;quot;goForward()&amp;quot;&amp;gt;back&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;document.querySelectorAll(&#39;.spa&#39;).forEach((item, index) =&amp;gt; {
    item.addEventListener(&#39;click&#39;, (e) =&amp;gt; {
        e.preventDefault();
        let link = item.textContent;
        window.history.pushState({name: `spa${index + 1}`}, link, link)
        console.log(link, &#39;pushState&#39;)
    }, false)
})

window.addEventListener(&#39;popstate&#39;, (e) =&amp;gt; {
    console.log(e.state)
})

function goBack() {
    window.history.back()
}

function goForward() {
    window.history.forward()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过监听点击事件，使用 pushState() 来修改 history 对象，下面的 gif 图演示了这个过程。需要注意的是，pushState() 和 replaceState() 方法只能修改路由，并不能让页面重新渲染。浏览器地址栏显示 demo/spa2.html 时，并不会跳转到 spa2.html 页面，也不会检查 spa2.html 页面是否存在，只是使其成为浏览器历史中的最新记录。&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597719961545.gif&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;hash&#34;&gt;hash&lt;/h3&gt;
&lt;p&gt;hash 是 location 对象的属性，它指的是当前 url 的锚，也就是从 # 号开始的部分。修改 location.hash 并监听 window 的 hashchange 事件，也能达到同样的目的。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;a class=&amp;quot;spa&amp;quot;&amp;gt;spa1.html&amp;lt;/a&amp;gt;
&amp;lt;a class=&amp;quot;spa&amp;quot;&amp;gt;spa2.html&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;document.querySelectorAll(&#39;.spa&#39;).forEach((item, index) =&amp;gt; {
    item.addEventListener(&#39;click&#39;, (e) =&amp;gt; {
        e.preventDefault();
        location.hash = index + 1
    }, false)
})

window.addEventListener(&#39;hashchange&#39;, (e) =&amp;gt; {
    console.log({ hash: location.hash })
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;演示效果如下：&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597720003223.gif&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;优缺点&#34;&gt;优缺点&lt;/h2&gt;
&lt;p&gt;SPA 可圈可点，现在已被大家广泛使用，也得到了主流框架的支持，但是它也有局限性，我们将它的优缺点总结如下。&lt;br&gt;
优点有：&lt;br&gt;
• 无刷新体验，用户在切换页面过程中不会频繁被“打断”，因为界面框架都在本地，对用户的响应非常及时，因此提升了用户体验；&lt;br&gt;
• 分离前后端关注点，前端负责界面显示，后端负责数据存储和计算，各司其职，不会把前后端的逻辑混杂在一起；&lt;br&gt;
• 减轻服务器压力，服务器只用出数据就可以，不用管展示逻辑和页面合成，吞吐能力会提高几倍；&lt;br&gt;
• API 共享，同一套后端程序代码，不用修改就可以用于Web界面、手机、平板等多种客户端；&lt;br&gt;
• 完全的前端组件化，前端开发不再以页面为单位，更多地采用组件化的思想，代码结构和组织方式更加规范化，便于修改和调整。&lt;br&gt;
缺点有：&lt;br&gt;
• 对 SEO 不太优好，尽管可以通过 Prerender 预渲染优化等技术解决一部分，但是相对还是不容易索引到它；&lt;br&gt;
• 易出错，需要使用程序管理前进、后退、地址栏等信息；&lt;br&gt;
• 较高的前端开发门槛，对技术能力要求较高，需要对设计模式有一定理解，因为面对不是一个简单的页面，而是一个运行在浏览器环境里面的桌面软件。&lt;/p&gt;
&lt;p&gt;文章来源：https://www.yuque.com/fe9/basic/xvftk8&lt;/p&gt;
">每天一个名词解释—单页应用</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-typescript/"" data-c="
          &lt;h2 id=&#34;官网介绍&#34;&gt;官网介绍&lt;/h2&gt;
&lt;p&gt;TypeScript 是 JavaScript 的类型的超集，它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。TypeScript 编译工具可以运行在任何服务器和任何系统上。TypeScript 是开源的。&lt;/p&gt;
&lt;h2 id=&#34;他人总结&#34;&gt;他人总结&lt;/h2&gt;
&lt;p&gt;typescript是由微软开发的一个javascript超集，本质是向javascript这门弱类型动态语言添加了静态类型和面向对象。作者是安德斯-海尔斯伯格，C#之父。从发布至今，typescript一直倍受关注，star数直线上升，并且被越来越多的个人和组织认可，首先是默认使用ts的angular系列框架，vue在2.2开始支持ts，2.5版本以后全面支持，包括vux,vue-router，在vue-cli3.0脚手架当中，ts被加入到默认选项当中。react后续也开始支持ts，包括增加jsx式的模板引擎tsx。后续更多的开源库也开始支持，包括element-ui、iView、AntD。&lt;/p&gt;
&lt;h2 id=&#34;优点&#34;&gt;优点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;提高代码质量，降低bug率，隐式类型转换带来大量不可预知的类型错误&lt;/li&gt;
&lt;li&gt;静态类型检测，减少编译阶段引起的错误&lt;/li&gt;
&lt;li&gt;模块化，es6已支持&lt;/li&gt;
&lt;li&gt;让代码更加清晰易读&lt;/li&gt;
&lt;li&gt;语法糖 ()=&amp;gt;，接口，枚举，泛型，方法重载&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;缺点&#34;&gt;缺点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;有一定的学习成本，需要理解接口（Interfaces）、泛型（Generics）、类（Classes）、枚举类型（Enums）等前端工程师可能不是很熟悉的概念&lt;/li&gt;
&lt;li&gt;短期可能会增加一些开发成本，毕竟要多写一些类型的定义，不过对于一个需要长期维护的项目，TypeScript 能够减少其维护成本&lt;/li&gt;
&lt;li&gt;集成到构建流程需要一些工作量&lt;/li&gt;
&lt;li&gt;可能和一些库结合的不是很完美&lt;/li&gt;
&lt;/ul&gt;
">每天一个名词解释—Typescript</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-ke-shi-hua/"" data-c="
          &lt;p&gt;如果要给可视化下一个定义，应该是这样的：可视化是将数据组织成易于为人所理解和认知的结构，然后用图形的方式形象地呈现出来的理论、方法和技术。实现可视化有两个关键要素，一个是数据，另一个是图形。如果要考虑在计算机上呈现，那还要加上交互。&lt;br&gt;
从工作内容来看，前端工程师主要负责处理内容呈现和用户交互。可视化的数据呈现，尤其是在Web端的呈现，属于前端工程师的范畴。但是，与传统的前端开发相比，可视化开发的工具、思路和方法，又和Web有着比较大的区别。&lt;/p&gt;
&lt;p&gt;首先是技术栈的不同。Web开发主要以HTML来描述结构，以CSS来描述表现，以JavaScript来描述行为。而可视化则较少涉及HTML和CSS，它更多地要同浏览器的Canvas、SVG、WebGl等其他图形API打交道。这是因为，Web开发以呈现块状内容为主，所以HTML是更合适的技术。而可视化开发则需要呈现各种各样的形状、结构，所以，形状更丰富的SVG以及更底层的Canvas2D和WebGL就是更合适的技术了。&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597590510836.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
其次，Web开发着重于处理普通的文本和多媒体信息，渲染普通的、易于阅读的文本和多媒体内容，而可视化开发则着重于处理结构化数据，渲染各种相对复杂的图表和图形元素。两者针对的信息特征和对图形渲染的要求有所不同，所以，在细节处理上也有比较大的差异。&lt;/p&gt;
&lt;p&gt;这么说比较抽象，举个例子。在使用ECharts这样现成的图标库开发图表的时候，往往会遇到一些产品需求不能很好被满足的情况。如果想要把图表的默认布局方式从absolute改变成其他方式、把坐标轴指示线的样式换成虚线、把配色换成线性渐变，或者想要修改地图中某个点的点击范围。虽然有的问题，通过修改参数配置（EChart的每种图表可能有数十种不同的配置项）确实能解决，但还是有一些问题必须要修改库的源码才能解决。&lt;/p&gt;
&lt;p&gt;因此，像EChart等现成的图表库，尽管功能强大、配置复杂，但是在样式细节控制上，仍然无法做到如CSS那般灵活。&lt;/p&gt;
&lt;p&gt;除此之外，可视化要处理更多偏视觉方面的细节信息，尤其是在要呈现的数据细节比较丰富的时候，可能要精确地呈现大小、距离、角度、高度、光线、阴影等等。这些细节的处理，都需要你对图形绘制有更加精确的控制，这就需要较深入地掌握图形学理论知识，了解并熟悉专业的图形库和绘图的工具。简而言之，就是Web开发的前端主要还是关注内容和样式，图形的渲染和绘制是由浏览器底层来完成的，而可视化前端，则可能要深入底层渲染层，真正去控制图形的绘制和细节的呈现。&lt;/p&gt;
&lt;p&gt;尽管Web前端与可视化在工具、思路和方法上有一些区别，但二者也有相通之处。&lt;/p&gt;
&lt;p&gt;其一，可视化与Web前端一样，最终都是以图像呈现在浏览器上，因此有许多通用的方法论。&lt;/p&gt;
&lt;p&gt;其二，二者都使用JavaScript，而且都是浏览器端的JavaScript。所以，就JavaScript的应用而言，这一块差别并不大。不过，可视化应用面对的数据和渲染的图形元素都比传统的Web应用更复杂一些，所以也就更加依赖JavaScript一些。&lt;/p&gt;
&lt;p&gt;其三，Web前端领域有许多成熟的工具，包括响应式框架（比如，三大框架Vue、React、Angular）、设计系统（比如Ant Design、ElementUI）、函数库（比如，Underscore、Lodash）等等。与Web前端一样，可视化领域也有丰富的JavaScript工具和活跃的生态，通常这些各种“开箱即用”的工具，就能够帮助你完成可视化开发。&lt;/p&gt;
&lt;p&gt;文章来源：https://zhuanlan.zhihu.com/p/158447352&lt;/p&gt;
">每天一个名词解释—可视化</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-/"" data-c="
          &lt;h2 id=&#34;什么是react&#34;&gt;什么是React&lt;/h2&gt;
&lt;p&gt;React是一个简单的javascript UI库，用于构建高效、快速的用户界面。它是一个轻量级库，因此很受欢迎。它遵循组件设计模式、声明式编程范式和函数式编程概念，以使前端应用程序更高效。它使用虚拟DOM来有效地操作DOM。它遵循从高阶组件到低阶组件的单向数据流。&lt;br&gt;
狭义来讲 React 是 Facebook 内部开源出来的一个前端 UI 开发框架，广义来讲 React 不仅仅是 js 框架本身，更是一套完整的前端开发生态体系，这套体系包括：&lt;br&gt;
React.js&lt;br&gt;
ReactRenders: ReactDOM / ReactServer / ReactCanvas&lt;br&gt;
Flux 模式及其实现（Redux , Fluxxor）&lt;br&gt;
React 开源组件&lt;br&gt;
React Native&lt;br&gt;
GraphQl + Relay&lt;/p&gt;
&lt;h2 id=&#34;什么是声明式编程&#34;&gt;什么是声明式编程&lt;/h2&gt;
&lt;p&gt;声明式编程是一种编程范式，它关注的是你要做什么，而不是如何做。它表达逻辑而不显式地定义步骤。这意味着我们需要根据逻辑的计算来声明要显示的组件。它没有描述控制流步骤。声明式编程的例子有HTML、SQL等&lt;/p&gt;
&lt;h2 id=&#34;什么是函数式编程&#34;&gt;什么是函数式编程&lt;/h2&gt;
&lt;p&gt;函数式编程是声明式编程的一部分。javascript中的函数是第一类公民，这意味着函数是数据，你可以像保存变量一样在应用程序中保存、检索和传递这些函数。&lt;br&gt;
函数式编程有些核心的概念，如下：&lt;br&gt;
不可变性(Immutability)&lt;br&gt;
纯函数(Pure Functions)&lt;br&gt;
数据转换(Data Transformations)&lt;br&gt;
高阶函数 (Higher-Order Functions)&lt;br&gt;
递归&lt;br&gt;
组合&lt;br&gt;
React 中一切都是组件。 我们通常将应用程序的整个逻辑分解为小的单个部分。 我们将每个单独的部分称为组件。 通常，组件是一个javascript函数，它接受输入，处理它并返回在UI中呈现的React元素。&lt;/p&gt;
">每天一个名词解释—React</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-electron/"" data-c="
          &lt;h1 id=&#34;是什么&#34;&gt;是什么&lt;/h1&gt;
&lt;h2 id=&#34;定义&#34;&gt;定义&lt;/h2&gt;
&lt;p&gt;Electron是一个能让你使用传统前端技术（Nodejs, Javascript, HTML, CSS）开发一个跨平台桌面应用的框架。这里所说的桌面应用指的是在Windows、OSX及Linux系统上运行的程序。&lt;br&gt;
可以认为Electron是一种运行环境库，我们可以基于此，用HTML、JS和CSS写桌面应用。&lt;br&gt;
我们熟知的一些软件都是基于electron开发的&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597377289775.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
像是vscode，atom，还有本博客使用的Gridea&lt;/p&gt;
&lt;h2 id=&#34;优点&#34;&gt;优点：&lt;/h2&gt;
&lt;p&gt;部署、升级方便。用户通过浏览器就可以访问；&lt;br&gt;
HTML/JS/CSS编写，方便且高效；&lt;br&gt;
windows、linux都支持；&lt;/p&gt;
&lt;h2 id=&#34;缺点&#34;&gt;缺点：&lt;/h2&gt;
&lt;p&gt;对于开发者：浏览器适配比较繁琐；&lt;br&gt;
对于开发者：有些应用，必须指定浏览器或版本。比如OCX必须是IE内核，H5要求浏览器必须是较高版本；&lt;br&gt;
对于用户：传统行业中，部分用户对web应用不习惯，尤其在专业工具软件方面，觉得web应用没有桌面应用用起来踏实。&lt;br&gt;
对于开发者：必须打开浏览器，输入一长串URL地址（虽然可以建立浏览器收藏夹或者创建URL的快捷方式到桌面，但大部分用户不会这么做）&lt;/p&gt;
&lt;h2 id=&#34;使用&#34;&gt;使用&lt;/h2&gt;
&lt;p&gt;安装 Electron&lt;br&gt;
&lt;code&gt;npm install --save-dev electron&lt;/code&gt;&lt;br&gt;
引入&lt;br&gt;
&lt;code&gt;const electron = require(&#39;electron&#39;)&lt;/code&gt;&lt;br&gt;
main.js配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const { app, BrowserWindow } = require(&#39;electron&#39;)
function createWindow () {   
  // 创建浏览器窗口
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })
  // 并且为你的应用加载index.html
  win.loadFile(&#39;index.html&#39;)
  // 打开开发者工具
  win.webContents.openDevTools()
}
// Electron会在初始化完成并且准备好创建浏览器窗口时调用这个方法
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(createWindow)
//当所有窗口都被关闭后退出
app.on(&#39;window-all-closed&#39;, () =&amp;gt; {
  // 在 macOS 上，除非用户用 Cmd + Q 确定地退出，
  // 否则绝大部分应用及其菜单栏会保持激活。
  if (process.platform !== &#39;darwin&#39;) {
    app.quit()
  }
})
app.on(&#39;activate&#39;, () =&amp;gt; {
  // 在macOS上，当单击dock图标并且没有其他窗口打开时，
  // 通常在应用程序中重新创建一个窗口。
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})
// 您可以把应用程序其他的流程写在在此文件中
// 代码 也可以拆分成几个文件，然后用 require 导入。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;官网地址：https://www.electronjs.org/&lt;br&gt;
中文文档：https://www.w3cschool.cn/electronmanual/&lt;br&gt;
官方文档：https://www.electronjs.org/docs&lt;/p&gt;
">每天一个名词解释—electron</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-gu-jia-ping-skeleton/"" data-c="
          &lt;p&gt;对于前端来讲，最重要的莫过于用户体验了，而从19年下半年开始，骨架屏这种提高用于体验的技术就开始被企业大量使用，我们平常对于需要请求加载的内容，可能用的比较多的是loading动画，比如在内容区域放一个菊花图，当请求结束，并且render tree构造完成后，将菊花图移除，展示用户想看的内容。虽然这种方式没啥缺点，但是现在更多的网站开始使用骨架屏代替，因为它能带过来更好的用户体验。&lt;br&gt;
骨架屏能让你的网页‘看起来’展现得更快，但只是看起来，实际上速度还是一样的。&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597325013432.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;骨架屏有哪些优势&#34;&gt;骨架屏有哪些优势&lt;/h2&gt;
&lt;p&gt;大体来说，骨架屏的优势在于：&lt;br&gt;
在页面加载初期预先渲染内容，提升感官上的体验。&lt;br&gt;
一般情况骨架屏和实际内容的结构是类似的，因此之后的切换不会过于突兀。这点和传统的 Loading 动图不同，可以认为是其升级版。&lt;br&gt;
只需要简单的 CSS 支持 (涉及图片懒加载可能还需要 JS )，不要求 HTTPS 协议，没有额外的学习和维护成本。&lt;br&gt;
如果页面采用组件化开发，每个组件可以根据自身状态定义自身的骨架屏及其切换时机，同时维持了组件之间的独立性。&lt;/p&gt;
&lt;h2 id=&#34;vue实现骨架屏&#34;&gt;Vue实现骨架屏&lt;/h2&gt;
&lt;p&gt;需要用到以下插件&lt;br&gt;
vue-server-renderer&lt;br&gt;
vue-skeleton-webpack-plugin&lt;br&gt;
page-skeleton-webpack-plugin&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597325346025.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
对比发现，就开发难度、灵活性和插件开源方来看，如果你的项目是基于vue-cli脚手架的，那么饿了么团队的page-skeleton-webpack-plugin是你的最佳选择，如果不是，那么你可以选择vue-router开源的vue-server-renderer.&lt;/p&gt;
&lt;p&gt;文章相关链接：&lt;br&gt;
vue骨架屏实践：https://www.jianshu.com/p/eacac700630e&lt;br&gt;
网页骨架屏自动生成方案：https://zhuanlan.zhihu.com/p/74403911&lt;br&gt;
如何让你的网页“看起来”展现地更快 —— 骨架屏二三事：https://zhuanlan.zhihu.com/p/48601348&lt;/p&gt;
">每天一个名词解释—骨架屏(Skeleton)</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/zi-mu-huan-xing-shi-bai-wen-ti/"" data-c="
          &lt;p&gt;今天面试问到了三栏布局，就自己尝试写一下，结果写出来中间那一栏的内容不能自动换行，试了半天也不行，换成flex也不行，最后去网上查了一下，原来超长的字母和数字是不会被自动拆开的，所以导致无法换行，解决方法就是加入&lt;code&gt;word-break: break-all;&lt;/code&gt;，通过这个就可以解决换行问题了。&lt;/p&gt;
">字母换行失败问题</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-nuxtjs/"" data-c="
          &lt;p&gt;Nuxt.js 是一个基于 Vue.js 的通用应用框架。&lt;br&gt;
通过对客户端/服务端基础架构的抽象组织，Nuxt.js 主要关注的是应用的 UI 渲染。&lt;br&gt;
Vue 开发一个单页面应用，相信很多前端工程师都已经学会了，但是单页面应用有一个致命的缺点，就是 SEO 极不友好。除非，vue 能在服务端渲染（ssr）并直接返回已经渲染好的页面，而并非只是一个单纯的 &lt;code&gt;&amp;lt;div id=&amp;quot;app&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;。&lt;br&gt;
Nuxt.js 就是一个极简的 vue 版的 ssr 框架。基于它，我们可以快速开发一个基于 vue 的 ssr 单页面应用。&lt;br&gt;
Nuxt.js 集成了以下组件/框架，用于开发完整而强大的 Web 应用：&lt;br&gt;
Vue 2&lt;br&gt;
Vue-Router&lt;br&gt;
Vuex (当配置了 Vuex 状态树配置项 时才会引入)&lt;br&gt;
Vue 服务器端渲染 (排除使用 mode: &#39;spa&#39;)&lt;br&gt;
Vue-Meta&lt;br&gt;
压缩并 gzip 后，总代码大小为：57kb （如果使用了 Vuex 特性的话为 60kb）。&lt;br&gt;
另外，Nuxt.js 使用 Webpack 和 vue-loader 、 babel-loader 来处理代码的自动化构建工作（如打包、代码分层、压缩等等）。&lt;/p&gt;
&lt;h2 id=&#34;特性&#34;&gt;特性&lt;/h2&gt;
&lt;p&gt;基于 Vue.js&lt;br&gt;
自动代码分层&lt;br&gt;
服务端渲染&lt;br&gt;
强大的路由功能，支持异步数据&lt;br&gt;
静态文件服务&lt;br&gt;
ES2015+ 语法支持&lt;br&gt;
打包和压缩 JS 和 CSS&lt;br&gt;
HTML 头部标签管理&lt;br&gt;
本地开发支持热加载&lt;br&gt;
集成 ESLint&lt;br&gt;
支持各种样式预处理器： SASS、LESS、 Stylus 等等&lt;br&gt;
支持 HTTP/2 推送&lt;br&gt;
以上内容来源网络&lt;br&gt;
总结:大致在网络上浏览了一下，了解了Nuxt.js的作用，服务端渲染，与其同作用的还有React的Next.js，目的就是利于SEO&lt;/p&gt;
">每天一个名词解释—Nuxt.js</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/es6-zhong-de-symbol/"" data-c="
          &lt;p&gt;ES6中引入了一种新的基础数据类型：&lt;code&gt;Symbol&lt;/code&gt;，它的功能类似于一种标识唯一性的ID。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let s1 = Symbol()
let s2 = Symbol(&#39;another symbol&#39;)
let s3 = Symbol(&#39;another symbol&#39;)
console.log(s1 == s2)   //false
console.log(s1 === s2)  //false
console.log(s2 == s3)   //false
console.log(s2 === s3)  //false
console.log(s1 == s1)   //true
console.log(s1 === s1)  //true
console.log(s2 === s2)  //true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它的值具有唯一性，除了自己它谁都不等于。&lt;br&gt;
&lt;code&gt;console.log(typeof s1) //symbol&lt;/code&gt;&lt;br&gt;
typeof的返回值为symbol&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let obj = {
            [Symbol(&#39;name&#39;)]: &#39;学习Symbol&#39;,
            age: 18,
            sex: &#39;male&#39;
        }
        console.log(Object.keys(obj)) // [&#39;age&#39;, &#39;sex&#39;]
        for (let p in obj) {
            console.log(p) // 分别输出：&#39;age&#39; 和 &#39;sex&#39;
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不能通过&lt;code&gt;Object.keys()&lt;/code&gt;或者&lt;code&gt;for...in&lt;/code&gt;来枚举&lt;br&gt;
使用JSON.stringify()将对象转换成JSON字符串的时候，Symbol属性也会被排除在输出内容之外：&lt;br&gt;
&lt;code&gt;console.log(JSON.stringify(obj)) // {&amp;quot;age&amp;quot;:18,&amp;quot;sex&amp;quot;:&amp;quot;male&amp;quot;}&lt;/code&gt;&lt;br&gt;
我们就没办法获取以Symbol方式定义的对象属性了么？非也。还是会有一些专门针对Symbol的API，比如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 使用Object的API
Object.getOwnPropertySymbols(obj) // [Symbol(name)]
// 使用新增的反射API
Reflect.ownKeys(obj) // [Symbol(name), &#39;age&#39;, &#39;title&#39;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后贴一下MDN的兼容表&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597161891981.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
可以看到并不被IE浏览器支持&lt;/p&gt;
">ES6中的Symbol</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-umijs/"" data-c="
          &lt;h2 id=&#34;什么是umijs&#34;&gt;什么是Umi.js?&lt;/h2&gt;
&lt;p&gt;Umi，中文可发音为乌米，是可扩展的企业级前端应用框架。Umi 以路由为基础的，同时支持配置式路由和约定式路由，保证路由的功能完备，并以此进行功能扩展。然后配以生命周期完善的插件体系，覆盖从源码到构建产物的每个生命周期，支持各种功能扩展和业务需求。你可以将它简单的理解为一个专注性能的类 next.js 前端框架，并通过约定、自动生成和解析代码等方式来辅助开发，减少我们开发者的代码量。&lt;br&gt;
为什么使用Umi.js?&lt;br&gt;
我们做react开发的时候会不会遇到以下问题？：&lt;br&gt;
1.项目做大的时候，开发调试的启动和热更新时间会变得很长。&lt;br&gt;
2.大应用下，网站打开很慢，有没有办法基于路由做到按需加载。&lt;br&gt;
3.dva的model每次都要手写载入，能否一开始就同项目初始化好？&lt;/p&gt;
&lt;p&gt;使用乌米，即可解决以上问题，并且还能提供如下优势：&lt;/p&gt;
&lt;p&gt;开箱即用，内置 react、react-router 等&lt;br&gt;
类 next.js 且功能完备的路由约定，同时支持配置的路由方式&lt;br&gt;
完善的插件体系，覆盖从源码到构建产物的每个生命周期&lt;br&gt;
一键兼容到 IE9&lt;br&gt;
完善的 TypeScript 支持&lt;br&gt;
与 dva 数据流的深入融合&lt;/p&gt;
&lt;p&gt;以上内容来源于网络，可能因为没有使用过React的原因?以上的内容听得我云里雾里，根本不知道是干什么的，后来翻到知乎上UmiJS作者发布umi 1.0的那篇文章，才大概看懂了些。&lt;/p&gt;
&lt;h2 id=&#34;umi-是什么&#34;&gt;umi 是什么？&lt;/h2&gt;
&lt;p&gt;umi 是一个类 next.js 的专注性能的前端框架，他的优势是：&lt;br&gt;
? 内置的大量性能优化&lt;br&gt;
? 多端，无缝支持容器和浏览器访问&lt;br&gt;
? 类 webpack 的插件机制&lt;br&gt;
? 针对 antd 和 dva 有友好的支持&lt;br&gt;
他基于以下约定：&lt;br&gt;
页面是 React 组件&lt;br&gt;
在 pages 目录下新增文件即可创建页面&lt;br&gt;
现在写一个 React 应用你需要掌握很多知识，比如基于路由的 code-splitting、service-worker、webpack 配置、babel 配置、aslant 配置、性能优化、HMR、redbox、jest 测试、ts 配置、tree-shaking、scope-hoist、side-effect 等等。umi 把这些枯燥的事情全都做了，而你只需负责创造性的那部分。&lt;br&gt;
&lt;code&gt;别的没看懂，umi可以把webpack 配置、babel 配置、jest 测试、ts 配置这里还是能看的懂的，总之就是各种简化操作&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;性能&#34;&gt;性能&lt;/h2&gt;
&lt;p&gt;umi 在性能上做了很多努力，这些对于开发者是无感知的。“你只管写业务代码，我会负责性能”，并且随着 umi 的迭代，我保证你的应用会越来越快。&lt;br&gt;
主要有：&lt;br&gt;
PWA Support&lt;br&gt;
Tree Shake&lt;br&gt;
antd(-mobile) 启用 ES Module&lt;br&gt;
Scope Hoist&lt;br&gt;
公共文件的智能提取&lt;br&gt;
页面级的按需加载&lt;br&gt;
Inline Critical CSS&lt;br&gt;
提供 umi/dynamic 和 import() 语法，分别用于懒加载组件和模块&lt;br&gt;
优化的 babel-preset-umi&lt;br&gt;
静态化的 SSR 处理&lt;br&gt;
link rel=preload&lt;br&gt;
hash 构建及服务端支持（云凤蝶）&lt;br&gt;
通过 react-constant-elements 和 react-inline-elements 提升 rerender 性能&lt;br&gt;
一键切换到 preact&lt;br&gt;
Progressive image loading&lt;br&gt;
按需打包 umi 内置的路由代码&lt;br&gt;
...&lt;br&gt;
&lt;code&gt;都是一些优化方面的&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;插件机制&#34;&gt;插件机制&lt;/h2&gt;
&lt;p&gt;webpack 的生态好，和他灵活的插件机制有很大关系。umi 也类似，他就是个架子，把坑挖好，然后通过插件让功能丰富起来，内部逻辑也是如此，由一个个插件组成。&lt;br&gt;
插件能做什么？基本什么都能做，整个生命周期都能修改，包括配置、build、dev、html 和 临时文件的生成等，已全部挖好坑。&lt;br&gt;
&lt;code&gt;现在是不是所有前端的，或者说编程有关的东西都在追求插件化?&lt;/code&gt;&lt;br&gt;
最后，这篇文章发于18年2月，网上的大部分讨论也是在那个时间，看起来Umi还没有火起来。&lt;/p&gt;
">每天一个名词解释—UmiJS</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/uniapp-xue-xi-ji-lu-day7/"" data-c="
          &lt;p&gt;试着写一下接口文档&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597136017703.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
Gridea写不了，换成飞书写了。&lt;/p&gt;
&lt;p&gt;接下来打算先把小程序上线一下，然后把后端放到服务器上，再把代码上传到github。&lt;br&gt;
因为之前的种种原因，最终服务器被我重置了，所以还要重新安装nodejs，然后把服务器的3000接口开放，接着用postman请求了一下&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597139974398.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
正常返回，看来是成功了。&lt;br&gt;
接下来打开小程序检测&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597140174788.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597140180203.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
一切正常，看来是成功了。&lt;br&gt;
在小程序内扫码预览，无法加载数据，看来小程序还有需要设置的地方。&lt;br&gt;
找了半天，发现如果想要加载数据，必须要对小程序域名进行设置，但我域名买下来还不到两天，还无法进行备案，估计还得再等几天才行了。&lt;br&gt;
借鉴了一下这篇文章https://www.cnblogs.com/zmdComeOn/archive/2019/08/20/11383572.html&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597141634414.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
成功上传到github。&lt;/p&gt;
">Uniapp学习记录day7</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-taro/"" data-c="
          &lt;p&gt;Taro 是一个开放式跨端跨框架解决方案，支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5 等应用。&lt;br&gt;
以上位Taro官网原文，原本我以为Vue的跨端框架解决方案是Uniapp，而React的跨端框架解决方案就是Taro，没想到Taro也是支持Vue的。两个跨端框架就官网来说，Taro要好看的多，更有设计感，不过文档示例还是以React为主。&lt;br&gt;
这里还有一篇选型对比文章：https://juejin.im/post/6844903768794857480&lt;br&gt;
文章写于19年1月底，还是比较有时效性的&lt;br&gt;
根据文章内的对比表格可以看到，在目前(19年初)的跨端解决方案中，唯有Taro与Uniapp，两者的github上的Star数量也相差不多&lt;br&gt;
另一篇写于19年4月：https://blog.csdn.net/z4909801/article/details/88943851&lt;br&gt;
文章对比了5个主流跨端框架，经过文章作者从生态、多端支持度、组件库、 接入成本、开源建设这5个方面的对比，可以看出Uniapp与Taro也是各有领先，虽然不是全方位领先其他框架，但也是位于顶部。&lt;br&gt;
而Taro最新版本位3.0，今年7月1日发布。&lt;br&gt;
另附一篇知乎上的文章：迄今为止，大前端各种多终端、跨端，解决方案合集https://zhuanlan.zhihu.com/p/100364496&lt;/p&gt;
">每天一个名词解释—Taro</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/uniapp-xue-xi-ji-lu-day6/"" data-c="
          &lt;h2 id=&#34;记一个小坑&#34;&gt;记一个小坑：&lt;/h2&gt;
&lt;p&gt;在创建Bucket的时候，要把权限设置为公共读，不然无法通过URL读取，这个博客也做了记载https://blog.csdn.net/wildwolf_001/article/details/83275924，不过这样设置以后打开URL也不是查看，而是直接下载，不过总比之前的XML报错好。&lt;/p&gt;
&lt;h2 id=&#34;又一个要注意的&#34;&gt;又一个要注意的：&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;module.exports = {
  upload,
  uploadimg,
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;这样暴露的要这样接收&#34;&gt;这样暴露的要这样接收&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;let {uploadimg} = require(&amp;quot;../oss/oss&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;关于前面提到的图片不能显示而是直接下载的问题，在阿里云的开发者社区里找到个提问帖，有人回复是需要绑定域名才可以预览图片，刚好浏览这个页面时，有个银川的短号打过来，刚好我也没有直接挂断而是接听了，那边是阿里OSS的客服，因为昨天我询问了关于这个的问题，今天有个电话回复，然后把文档发我QQ邮箱了，不得不说客服的态度很好。&lt;br&gt;
可惜态度好也不能解决问题，也不知道是我没表述清楚还是什么，不过最终还是找到了https://help.aliyun.com/document_detail/142631.html，如果Bucket是在19年9月23日前创建的，是可以预览的，在那之后的使用OSS默认域名生成的文件URL从浏览器访问时会以附件形式下载，使用自有域名生成的文件URL访问时，可以预览文件内容。看来还是要绑定域名，不过这有个前提，对于图片文件（在未修改文件http头的情况下），不清楚这里的未修改文件http头是指什么，可是我详情里面看到HTTP是设置过的，针对不同文件也有不同的解析，而且我上传了一个PDF文件，解析的HTTP头里的Content-Type也是application/pdf，而且输入URL也能正常浏览无需下载，看来还是要绑定域名。&lt;/p&gt;
&lt;h2 id=&#34;开始数据联调&#34;&gt;开始数据联调&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1597052848420.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
这边数据是没什么问题的&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597052902526.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
上来就开始给我报错(ps:传图片的时候发现Gridea不允许上传同名图片)&lt;br&gt;
找了个有关的帖子http://www.wxappclub.com/topic/798，如果填了小程序APPID就必须满足三个条件&lt;br&gt;
1.必须是https协议&lt;br&gt;
2.tls 必须在 1.2 及以上版本&lt;br&gt;
3.必须在小程序的后台（不是接口的后台），配置上https请求&lt;br&gt;
解决办法是取消小程序APPID&lt;br&gt;
在Uniapp上解绑了，但是小程序页不跳出之前的未绑定APPID的报错，看来要在开发者工具上面操作，详情里的APPID无法修改，按网上说的该project.config.json里的，打开看这里的压根也不是我的APPID啊，改了也没用。&lt;br&gt;
排查了半天，原来是没写http，本地配置里的不校验合法域名那一条是默认勾选的(大概)。&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597054724070.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
">Uniapp学习记录day6</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/uniapp-xue-xi-ji-lu-day5/"" data-c="
          &lt;h2 id=&#34;先安装一个跨域用的&#34;&gt;先安装一个跨域用的&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;var cors = require(&#39;koa-cors&#39;);
app.use(cors());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过这个就可以进行跨域请求了&lt;/p&gt;
&lt;h2 id=&#34;koa-multer&#34;&gt;koa-multer&lt;/h2&gt;
&lt;p&gt;用来上传图片的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const multer = require(&amp;quot;koa-multer&amp;quot;);
// const uploadSingle = multer.single(&amp;quot;file&amp;quot;);
// 图片类上传到后端文件夹
let storage = multer.diskStorage({   // diskStorage:存储
    // 图片存储路径
    destination:(req,file,cb) =&amp;gt;{
        cb(null,&#39;public/uploads/&#39;)
    }
})
// 配置multer
let upload = multer({storage})
module.exports = upload
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在中间件中引入&lt;br&gt;
&lt;code&gt;const forYou = require(&amp;quot;../../models/foryou&amp;quot;);&lt;/code&gt;&lt;br&gt;
&lt;code&gt;upload.single(&amp;quot;file&amp;quot;)&lt;/code&gt;通过这种方式可以处理上传的图片&lt;br&gt;
设置路由&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;router.post(&amp;quot;/foryou&amp;quot;, upload.single(&amp;quot;file&amp;quot;), async (ctx) =&amp;gt; {
  console.log(&amp;quot;foryou&amp;quot;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看到图片已经上传完成&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1596976747126.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
做一下优化&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;filename: (req, file, cb) =&amp;gt; {
    console.log(file);
    let fileFormat = (file.originalname).split(&#39;.&#39;)
    console.log(fileFormat)
    // 时间戳
    cb(null,Date.now()+&#39;.&#39;+fileFormat[fileFormat.length-1])
  },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1596977619788.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
PS:做到这里不由想起今天看到的关于nest与koa的对比，提到koa是较为底层的，而nest是一整套的，以我以前用过的thinkphp为例，上传图片功能很简单，还可以自己选择图片的命名格式，而koa上传图片也需要额外的插件，还要自己写图片命名格式，两相比较还是tp的好一些，也让我对于nest有了更多的想学的冲动了。&lt;br&gt;
配置一下阿里云的OSS，用来存储项目图片。&lt;br&gt;
顺便买了个域名。&lt;/p&gt;
&lt;h2 id=&#34;使用oss的sdk&#34;&gt;使用OSS的SDK&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;npm install ali-oss --save
&lt;/code&gt;&lt;/pre&gt;
">Uniapp学习记录day5</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/mei-tian-yi-ge-ming-ci-jie-shi-nestjs/"" data-c="
          &lt;p&gt;Nest是一个用于构建高效，可扩展的Node.js服务器端应用程序的框架。它使用渐进式JavaScript，使用TypeScript构建（保留与纯JavaScript的兼容性），并结合了OOP（面向对象编程），FP（功能编程）和FRP（功能反应编程）的元素。&lt;br&gt;
以上为官网原话，虽然写了是什么，但对于新人的我还是看的一脸懵逼，然后网上搜索了一下，知乎里有篇专栏写的很详细，然后关于Nest的提问里大家也做了很多讨论，我这里总结一下。&lt;br&gt;
Nest 是 Node.js 版的 Spring 框架。Nest大量借鉴了Java Spring 框架和 Angular的特性，相比于Koa和Express，Nest更加全面，更加上层，Nest提供了一种开箱即用的应用程序体系结构，该体系结构允许开发人员和团队创建高度可测试，可伸缩，松散耦合且易于维护的应用程序。&lt;br&gt;
Nest 是一种完整的解决方案&lt;br&gt;
包含了认证、数据库、上传文件、验证、缓存、序列化、记录器、安全、配置、压缩、请求等开箱即用的技术。&lt;br&gt;
Nest可以看作是所有Koa-xxx的功能集合，并且再nNpm上Nest也是涨势惊人，未来可期。我个人感觉可能是以后的Nodejs后端扛把子。很有学习的必要。&lt;/p&gt;
">每天一个名词解释—nest.js</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/vuetify-xue-xi-ji-lu/"" data-c="
          &lt;p&gt;elementUI已经慢慢不再维护的今天，学习一个新的UI框架对我来说就尤为重要了，对比了下iview和vuetify的官方文档和npm上的周下载量以及迭代的版本与最近更新时间，最终还是选择先学习vuetify。&lt;/p&gt;
&lt;p&gt;在vue项目中安装&lt;br&gt;
&lt;code&gt;vue add vuetify&lt;/code&gt;&lt;br&gt;
查看package.json发现已经安装完成&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597203946038.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
可以使用Vuetify的预置布局完成页面的基础布局&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1597211156600.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
除此以外，还提供了从简单到复杂的8种布局方式。&lt;br&gt;
不过因为是学习，所以我打算自己组装一个页面的基本布局。&lt;/p&gt;
">vuetify学习记录</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/1/"" data-c="
          &lt;p&gt;今天的主要内容应该还是koa和数据库&lt;/p&gt;
&lt;p&gt;Robo 3T 和 Compass删除对比&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1596876580748.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1596876584566.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
都需要额外的一步&lt;/p&gt;
&lt;p&gt;koa返回状态码：ctx.status&lt;br&gt;
状态码大全：http://tools.jb51.net/table/http_status_code&lt;/p&gt;
&lt;p&gt;记一个坑：&lt;br&gt;
通过中间件来捕获全局异常时，要把中间件放在use的最前面,不然就会出错。&lt;/p&gt;
">Uniapp学习记录day4</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/fang-dou-he-jie-liu/"" data-c="
          &lt;h2 id=&#34;函数防抖&#34;&gt;函数防抖&lt;/h2&gt;
&lt;p&gt;函数防抖是优化高频率执行js代码的一种手段&lt;br&gt;
可以让被调用的函数在一次连续的高频操作中只被调用一次&lt;/p&gt;
&lt;p&gt;作用：减少代码执行次数, 提升网页性能&lt;br&gt;
应用场景：oninput / onmousemove / onscroll / onresize 等事件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function debounce(fn, wait) {
            let timer
            return function () {
                // 改变执行函数内部this指向
                let _this = this
                let _args = arguments
                clearTimeout(timer)
                timer = setTimeout(function () {
                    fn.apply(_this, _args)
                }, wait)
            }
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;函数节流&#34;&gt;函数节流&lt;/h2&gt;
&lt;p&gt;函数节流是优化高频率执行js代码的一种手段&lt;br&gt;
可以减少高频调用函数的执行次数&lt;/p&gt;
&lt;p&gt;作用：减少代码执行次数, 提升网页性能&lt;br&gt;
应用场景：oninput / onmousemove / onscroll / onresize 等事件&lt;br&gt;
第一次不执行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function throttle(fn, wait) {
            let timer
            return function () {
                if (timer) return
                let _this = this
                let _args = arguments
                timer = setTimeout(() =&amp;gt; {
                    fn.apply(_this, _args)
                    timer = null
                }, wait)
            }
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后一次不执行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function throttle(fn, wait) {
            let old = 0
            return function () {
                let _this = this
                let _args = arguments
                // 获取当前的时间戳
                let now = new Date().valueOf()
                if (now - old &amp;gt; wait) {
                    fn.apply(_this, _args)
                    // 立即执行
                    old = now;
                }
            }
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;函数节流和函数防抖区别&#34;&gt;函数节流和函数防抖区别&lt;/h2&gt;
&lt;p&gt;函数节流是减少连续的高频操作函数执行次数 (例如连续调用10次, 可能只执行3-4次)&lt;br&gt;
函数防抖是让连续的高频操作时函数只执行一次(例如连续调用10次, 但是只会执行1次)&lt;/p&gt;
&lt;p&gt;参考&lt;br&gt;
https://www.bilibili.com/video/BV1pQ4y1M71e?p=1&lt;/p&gt;
">防抖和节流</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/shou-cang-de-yi-xie-you-yong-de-wang-zhan/"" data-c="
          &lt;p&gt;学习类：&lt;br&gt;
B站：https://www.bilibili.com/&lt;br&gt;
没错，就是B站，基本上我和同学在网上学习的编程知识很大比例来自B站，有很多教育机构或者个人上传的编程有关的视频。&lt;br&gt;
掘金：https://juejin.im/&lt;br&gt;
知乎：https://www.zhihu.com/&lt;br&gt;
思否：https://segmentfault.com/&lt;br&gt;
简书：https://www.jianshu.com/&lt;br&gt;
CSDN：https://www.csdn.net/&lt;br&gt;
博客园：https://www.cnblogs.com/&lt;br&gt;
除了知乎、简书，剩下的都是开发者社区了，也基本是我所知的最大的了，这其中CSDN问题最大，页面又杂又乱，还有广告，而且有很多很古老的文章也都还被频繁检索出来，上次搜个数据，打开了个03年的帖子，发文章也是，明明写了原创，结果在第一行就是原文地址，信息太杂，上次有个报错，在CSDN的一篇文章里找解决方法，顺着原文地址找了3层，跑到博客园去了。还有就是知乎的网页端也过于简陋了吧，浏览文章的页面我毕设加点东西都快和它差不多了，体验很差，思否的手机端也是特不好用，登录都登录不了，是不是已经不维护了？简书最大的问题就是没多久就维护一次，而且是全站的，经常搜到信息点进去显示网站维护。博客园就是界面太老旧了，最近可能进行了UI升级？多少比之前好看些了。&lt;br&gt;
看云：https://www.kancloud.cn/explore&lt;br&gt;
以前学习TP5的时候，就实在看云看的文档，还有很多其他的文档，不过还是以PHP为主。&lt;br&gt;
PHP中文网：https://www.php.cn/&lt;br&gt;
也是以前学PHP的时候收藏的网站，但我记得网站页面比较简陋，而且站长好像说过不搞了，也不知道现在这个是以前的在搞还是换人了，也没用过了。&lt;br&gt;
软件类：&lt;br&gt;
3D溜溜网：https://zixue.3d66.com/&lt;br&gt;
虽然是个自学网站，但是上面的视频我都没看过，但是这个网站最大的优点是所有它这里开设的课程的破解版软件它基本都有，而且很新，是个很不错的资源网站。&lt;br&gt;
MSDN：http://msdn.itellyou.cn/&lt;br&gt;
可以说是windows全家桶网站，windows的全部产品这里几乎都有，像是Access，Office，Visual Basic,还有不同版本的windows系统，还有一大推我听都没听过的。&lt;br&gt;
设计类：&lt;br&gt;
中国色：http://zhongguose.com/#shenyanhong&lt;br&gt;
选修的PPT课老师推荐的网站，是一个展示配色的网站，基本都是中式配色，像是什么绀紫、靛青、景泰蓝这种名字的颜色。&lt;br&gt;
站酷：https://www.zcool.com.cn/&lt;br&gt;
各式各样的设计，涵盖了设计的全部种类，应该是国内最大的设计网站了。&lt;br&gt;
removebg：https://www.remove.bg/zh&lt;br&gt;
可以消除图片中的背景，比我自己用PS抠的好N倍，直接可以开淘宝店抠图的水平，不过我之前用没有中文版，而且也不需要登录，这中文版是要收费了吗？&lt;br&gt;
Behance：https://www.behance.net/&lt;br&gt;
很好的一个设计网站，好像是adobe下的，有很多有创意的作品。&lt;br&gt;
游戏类：https://ygodl.com/&lt;br&gt;
决斗链接中文网，是玩家自己组建的，最近随着水哥在B站的游戏王视频带来的热度，决斗链接中文网也是迎来了一大批新人，作为“老”用户也是颇感欣慰。&lt;br&gt;
动漫类：&lt;br&gt;
zzzfun：http://www.zzzfun.com/&lt;br&gt;
D站倒了的今天，zzz还算一方净土。&lt;/p&gt;
">收藏的一些有用的网站</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/yi-xie-qian-duan-ui-kuang-jia/"" data-c="
          &lt;p&gt;之前做毕设的时候也大概看了几个UI框架，不过是在项目已经进行到一半以后才开始的，所以也没有使用的机会，前几天做的移动端的小demo用了下有赞的Vant，感觉很不错，就又整理了一下，找了一些目前比较流行的前端UI框架，做一个汇总。&lt;br&gt;
一、WeUI&lt;br&gt;
官网地址：https://weui.io/&lt;br&gt;
github：https://github.com/Tencent/weui&lt;br&gt;
文档地址1：https://github.com/Tencent/weui.js/tree/master/docs&lt;br&gt;
文档地址2：http://old.jqweui.com/components&lt;br&gt;
官网的介绍说是同微信原生视觉体验一致的样式库，然后官网地址里没有文档？还是说我没找到?然后github里好像有一个文档，但是不是很方便，还有个网上找的，不过名字是jQuery WeUI，还带着版本号，好像是别人做的，不过里面有WeUI基础组件的文档。&lt;br&gt;
二、Mint UI&lt;br&gt;
官网地址：https://mint-ui.github.io/#!/zh-cn&lt;br&gt;
github：https://github.com/ElemeFE/mint-ui&lt;br&gt;
饿了么的移动端UI库，不论是文档还是示例都很好，很直观的就能看到效果，左边代码右边图示，不过我去github上看了一下，已经不再维护了。&lt;br&gt;
三、View UI&lt;br&gt;
官网地址：https://www.iviewui.com/&lt;br&gt;
github：https://github.com/view-design/ViewUI&lt;br&gt;
终于有个PC端的，虽然移动端的UI各个小巧精妙，但是我还是更喜欢PC端的UI。原名叫 iView，现已改名View UI，文档写的也很好，去网上找了下是TalkingData开发的，没听过的公司。&lt;br&gt;
四、element UI&lt;br&gt;
官网地址：https://element.eleme.cn/#/zh-CN&lt;br&gt;
github：https://github.com/ElemeFE/element&lt;br&gt;
也是饿了么团队出品的，也是我唯一一个大量使用过的，在国内可能也是github上星最多的吧？不过最近知乎上看到说是更新频率下降了，也不知道什么原因。&lt;br&gt;
五、layUI&lt;br&gt;
官网地址：https://www.layui.com/&lt;br&gt;
github：https://github.com/sentsin/layui/&lt;br&gt;
这个是我最早听说的UI框架了，那时我还是个懵懵懂懂的少年，也不知道什么前后端，为了完成老师的作业，网上找了个模板，就找了个layUI的，那时候也不会js，拿着这模板怎么也用不好，最后把大部分功能都删了，才终于让网页跑起来，都是泪啊。&lt;br&gt;
搜了一下好像没找到公司，然后知乎上是评价作者，那应该是个人开发的，膜拜大佬。&lt;br&gt;
六、Bootstrap&lt;br&gt;
官网地址：https://www.bootcss.com/&lt;br&gt;
github：https://github.com/twbs&lt;br&gt;
文档地址v4：https://v4.bootcss.com/docs/getting-started/introduction/&lt;br&gt;
文档地址v3：https://v3.bootcss.com/css/&lt;br&gt;
也是大名鼎鼎的UI框架了，Twitter开发的，我是同时接触的layUI和Bootstrap，也是因为网上基本就这两个的模板。有v3和v4两个版本的文档，v4本地化还不完全，这两天在B站和youtube上看到了v5版的教学了。忘了在哪里好像看到过bootstrap-vue，npm上显示周下载量有36W，上次更新是9天前，更新频率也很高，有时间要用下试试。&lt;br&gt;
七、vant&lt;br&gt;
官网地址：https://youzan.github.io/vant/#/zh-CN/&lt;br&gt;
github：https://github.com/youzan/vant&lt;br&gt;
有赞出品，移动端框架，文档和示例都很不错，而且涵盖的组件类型也很多，前几天的demo中用过，sku这个组件稍显复杂，也用了一下新了解的骨架屏，总体体验很不错。&lt;br&gt;
八、flutter&lt;br&gt;
官网地址：https://flutterchina.club/&lt;br&gt;
github：https://github.com/flutter/flutter&lt;br&gt;
有中文网，是谷歌的移动端UI框架，听说过，不过还没学习使用，文档还可以，不过好像图示有点少？全是文字看着头大。&lt;br&gt;
九、Cube-UI&lt;br&gt;
官网：https://didi.github.io/cube-ui/#/zh-CN&lt;br&gt;
github：https://github.com/didi/cube-ui&lt;br&gt;
听说是滴滴团队开发的，是个移动端的框架。&lt;br&gt;
十、at-ui&lt;br&gt;
官网：https://at-ui.github.io/at-ui/#/zh&lt;br&gt;
github：https://github.com/at-ui/at-ui&lt;br&gt;
阿里的，不过听说已经不在维护了，可惜我还没用过。&lt;br&gt;
XI、Pure.css&lt;br&gt;
官网：https://www.purecss.cn/&lt;br&gt;
有中文站，雅虎出品，应该不算UI框架，不过我个人十分喜欢，尤其是它的配色，特别好看。&lt;br&gt;
十一、antd&lt;br&gt;
官网：https://ant.design/docs/react/introduce-cn&lt;br&gt;
github：https://github.com/ant-design/ant-design/&lt;br&gt;
看名字就知道这是阿里系的，蚂蚁金服出品，主要用于中后台，不过这个是react的UI组件库，还要先学习react才能使用。&lt;br&gt;
十二、Vuetify&lt;br&gt;
官网：https://vuetifyjs.com/zh-Hans/&lt;br&gt;
github：https://github.com/vuetifyjs/vuetify&lt;br&gt;
github星数有26.9K，比iview多出3.5K，最近一次更新是两天前，最近一周下载也有35W，最重要的是官方文档还用了骨架屏，在elementUI慢慢不再维护的今天，Vuetify应该是下一个elementUI了。&lt;/p&gt;
">一些前端UI框架</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/uniapp-xue-xi-ji-lu-day3/"" data-c="
          &lt;p&gt;今天又是学习的一天！！！&lt;/p&gt;
&lt;p&gt;这页面没数据实在是不行啊，果然后端也要写啊&lt;/p&gt;
&lt;p&gt;切记切记，安装mongoDB一定要记得，把那个✅给去掉，太坑了！！！！&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1596782694203.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
安装了2个多小时，最后程序还崩溃了。&lt;/p&gt;
&lt;p&gt;哎，阿里云的MongoDB贵的有些离谱了，只能在自己服务器上搭一个了。&lt;/p&gt;
&lt;p&gt;1.先进入阿里的云服务器，然后下载安装nodejs，再远程连接服务器，把本地的mongdb安装文件传给服务器(怕服务器下载太慢)，然后等待安装，切记不要勾选安装compass&lt;/p&gt;
&lt;p&gt;2.安装好后配置环境变量，找了网上几个教程，好像版本都对不上，有要创建data文件夹的有要创建log文件夹的，但是我发现server文件夹下面有bin、log目录，把bin目录的地址放入环境变量，cmd中输入mongo还是不行，关闭后重新打开就能显示mongodb版本了。&lt;/p&gt;
&lt;p&gt;3.这配置运行环境的坑可太多了，大概记一下在放几个链接吧。&lt;br&gt;
服务中创建的MongoDB server 无法启动、关闭、重启&lt;br&gt;
解决办法：https://blog.csdn.net/yqwang75457/article/details/84949915&lt;br&gt;
mongodb设置用户名密码权限：&lt;br&gt;
https://blog.csdn.net/qq_37925422/article/details/80445591&lt;br&gt;
https://www.mongodb.org.cn/manual/104.html&lt;/p&gt;
&lt;p&gt;淦，感觉出大问题了，先把服务器重置了吧。&lt;br&gt;
先连本地连接数据库&lt;br&gt;
安装一个mongoose：cnpm i mongoose --save&lt;br&gt;
然后配置连接，然后因为它是一个promise，所以可以then和catch，不过还是不太明白是怎么操作的。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const Schema = mongoose.Schema;
// mongodb里没有表,叫做文档或者集合
// 每一个Schema对应mongodb中的一个集合
// 实例化数据模板:注册功能字段
const NameSchema = new Schema({
  // 注册对象模型
  name: {
    type: String,
    require: true,
  },
  password: {
    type: String,
    require: true,
  },
  openid: {
    type: String,
    require: true,
  },
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;module.exports = userInfo = mongoose.model(&amp;quot;user_info&amp;quot;, NameSchema);&lt;br&gt;
这个没有代码块的功能也是很烦。&lt;br&gt;
教程里是定义了一个Schema对象，然后它的实例里有name、password等字段，有个type属性来限定数据类型，有个require属性来限定是否为空？不知道是不是可以这么理解，这里还是能通过mysql来类比一下的，就是mysql的数据类型和是否为空，然后以userInfo的名字暴露出去&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;router.post(&amp;quot;/register&amp;quot;, async (ctx) =&amp;gt; {
  console.log(&amp;quot;这是注册&amp;quot;);
  // console.log(ctx.request.body)
  // console.log(ctx.request.body.name)
  let { name, password, openid } = ctx.request.body;
  const user_info = new userInfo({
    name: name,
    password: password,
    openid: openid,
  });
  // 存储到数据库
  await user_info
    .save()
    .then((res) =&amp;gt; {
      console.log(&amp;quot;success&amp;quot;);
    })
    .catch((e) =&amp;gt; {
      console.log(e);
    });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这一边是通过前面暴露的userInfo作为实例对象，把前端传来的值赋给它，然后通过.save()方法存储到数据库&lt;/p&gt;
&lt;p&gt;服务器上的终于搞定了，再把数据库的连接从本地切换为服务器。&lt;br&gt;
☀️☀️✨✨⚡️成功联通⚡️🌈🌈🏳️‍🌈🏳️‍🌈&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1596811047642.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
&lt;img src=&#34;https://jujuul.github.io//post-images/1596861176847.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;
">Uniapp学习记录day3</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/uniapp-xue-xi-ji-lu-day2/"" data-c="
          &lt;p&gt;开搞开搞，开始之前先在网上搜索了下小程序怎么上线，毕竟我自己也有的个公众号，把项目上线一下岂不美哉?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1596709131676.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;br&gt;
这个图标切换和阴影背景的显示隐藏真是够麻烦的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const query = wx.createSelectorQuery()
query.select(&#39;#boxFixed&#39;).boundingClientRect()
query.selectViewport().scrollOffset()
query.exec((res) =&amp;gt; {
    this.menutop = res[0].top
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用来返回选中节点的TOP位置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wx.pageScrollTo({
    scrollTop: this.menutop,
    duration: 300
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用来使页面滚动到选择的位置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:catchtouchmove=&amp;quot;true&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;专门用来解决小程序的事件穿透&lt;/p&gt;
">Uniapp学习记录day2</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/uni-app-xue-xi-ji-lu-day1/"" data-c="
          &lt;p&gt;uniapp生成小程序遇到的坑&lt;br&gt;
1.小程序内不能用id选择器&lt;br&gt;
2.小程序的声明周期函数不能用在子组件里，要用在父组件&lt;br&gt;
3.小程序没有window对象,没有document对象等等……&lt;br&gt;
4.uniapp没有vue原生的router路由，而是使用uni路由，较VUE更为方便&lt;/p&gt;
&lt;figure data-type=&#34;image&#34; tabindex=&#34;1&#34;&gt;&lt;img src=&#34;https://jujuul.github.io//post-images/1596643726837.PNG&#34; alt=&#34;&#34; loading=&#34;lazy&#34;&gt;&lt;/figure&gt;
&lt;p&gt;学到的知识：&lt;br&gt;
在pages.json中可以对全局进行配置，有关页面的路径、窗口样式、导航栏、底部tabbar等都在这里。&lt;br&gt;
全局配置与单页配置要自己取舍。&lt;br&gt;
每个对象内的最后一项都没有逗号&lt;br&gt;
像素单位是upx，可以设置upx与px的比值来进行转换，不过我看网上都推荐使用 rpx。&lt;br&gt;
显示文字使用&lt;text&gt;&lt;/text&gt;标签&lt;br&gt;
显示图片使用&lt;image&gt;&lt;/image&gt;标签&lt;br&gt;
&lt;view&gt;&lt;/view&gt;用来取代div标签&lt;br&gt;
&lt;block&gt;&lt;/block&gt;标签很好用，很多for循环都写在block标签内&lt;br&gt;
其余的都和vue差不多，用了两个vue没有的声明周期onload和onshow，好像是微信小程序的生命周期。&lt;/p&gt;
&lt;p&gt;一开始一直报错没有appid，登陆了微信的开发者平台复制了appid，结果还是不行，检查发现是复制了公众号的appid，又赶紧注册了小程序，网上例子的后端接口好像不开放，有必要自己写一个，顺便复习下nodejs和koa2，或者express也行。&lt;/p&gt;
&lt;p&gt;总体而言，第一天的uniapp体验还不错，主要是语法基本都是vue的，难点在于各个组件，属性一大推，而且感觉说明不是很好，阅读起来很累。&lt;/p&gt;
">Uniapp学习记录day1</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/xue-xi-mu-biao/"" data-c="
          &lt;p&gt;在这里记录一下接下来要学习的东西&lt;/p&gt;
&lt;p&gt;TypeScript&lt;br&gt;
Flutter	uniapp	跨端&lt;br&gt;
React&lt;br&gt;
Taro&lt;br&gt;
umijs&lt;br&gt;
Hooks&lt;br&gt;
Serverless&lt;br&gt;
可视化&lt;br&gt;
SSR&lt;br&gt;
Nextjs&lt;br&gt;
后端  go	nodejs	java&lt;/p&gt;
">学习目标</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/about/"" data-c="
          &lt;blockquote&gt;
&lt;p&gt;欢迎来到我的小站呀，很高兴遇见你！🤝&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;关于本站&#34;&gt;🏠 关于本站&lt;/h2&gt;
&lt;h2 id=&#34;博主是谁&#34;&gt;👨‍💻 博主是谁&lt;/h2&gt;
&lt;h2 id=&#34;兴趣爱好&#34;&gt;⛹ 兴趣爱好&lt;/h2&gt;
&lt;h2 id=&#34;联系我呀&#34;&gt;📬 联系我呀&lt;/h2&gt;
">关于</a>
      </div>
      
      <div class="item">
        <a class="result-title" style="opacity: 0;" href="https://jujuul.github.io/post/hello-gridea/"" data-c="
          &lt;p&gt;👏  欢迎使用 &lt;strong&gt;Gridea&lt;/strong&gt; ！&lt;br&gt;
✍️  &lt;strong&gt;Gridea&lt;/strong&gt; 一个静态博客写作客户端。你可以用它来记录你的生活、心情、知识、笔记、创意... ...&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/getgridea/gridea&#34;&gt;Github&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;https://gridea.dev/&#34;&gt;Gridea 主页&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;http://fehey.com/&#34;&gt;示例网站&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;特性&#34;&gt;特性👇&lt;/h2&gt;
&lt;p&gt;📝  你可以使用最酷的 &lt;strong&gt;Markdown&lt;/strong&gt; 语法，进行快速创作&lt;/p&gt;
&lt;p&gt;🌉  你可以给文章配上精美的封面图和在文章任意位置插入图片&lt;/p&gt;
&lt;p&gt;🏷️  你可以对文章进行标签分组&lt;/p&gt;
&lt;p&gt;📋  你可以自定义菜单，甚至可以创建外部链接菜单&lt;/p&gt;
&lt;p&gt;💻  你可以在 &lt;strong&gt;Windows&lt;/strong&gt;，&lt;strong&gt;MacOS&lt;/strong&gt; 或 &lt;strong&gt;Linux&lt;/strong&gt; 设备上使用此客户端&lt;/p&gt;
&lt;p&gt;🌎  你可以使用 &lt;strong&gt;𝖦𝗂𝗍𝗁𝗎𝖻 𝖯𝖺𝗀𝖾𝗌&lt;/strong&gt; 或 &lt;strong&gt;Coding Pages&lt;/strong&gt; 向世界展示，未来将支持更多平台&lt;/p&gt;
&lt;p&gt;💬  你可以进行简单的配置，接入 &lt;a href=&#34;https://github.com/gitalk/gitalk&#34;&gt;Gitalk&lt;/a&gt; 或 &lt;a href=&#34;https://github.com/SukkaW/DisqusJS&#34;&gt;DisqusJS&lt;/a&gt; 评论系统&lt;/p&gt;
&lt;p&gt;🇬🇧  你可以使用&lt;strong&gt;中文简体&lt;/strong&gt;或&lt;strong&gt;英语&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;🌁  你可以任意使用应用内默认主题或任意第三方主题，强大的主题自定义能力&lt;/p&gt;
&lt;p&gt;🖥  你可以自定义源文件夹，利用 OneDrive、百度网盘、iCloud、Dropbox 等进行多设备同步&lt;/p&gt;
&lt;p&gt;🌱 当然 &lt;strong&gt;Gridea&lt;/strong&gt; 还很年轻，有很多不足，但请相信，它会不停向前 🏃&lt;/p&gt;
&lt;p&gt;未来，它一定会成为你离不开的伙伴&lt;/p&gt;
&lt;p&gt;尽情发挥你的才华吧！&lt;/p&gt;
&lt;p&gt;😘 Enjoy~&lt;/p&gt;
">Hello Gridea</a>
      </div>
      
    </div>
    <div class="page">
      <div id="page_ul"></div>
    </div>
  </div>
</div>
<script>
  !function () {
    let searchMask = document.querySelector('#search_mask');
    let result = document.querySelector('#result');
    let items = document.querySelectorAll('.item');
    let searchBox = document.querySelector('#search');
    let statCount = document.querySelector('#stat_count');
    let statTimes = document.querySelector('#stat_times');
    let pageUl = document.querySelector('#page_ul');
    let close = document.querySelector('#close');
    
    close.addEventListener('click', function() {
      searchMask.style = 'display: none;'
    })

    let finds = [];
    let contents = [];
    let pageSize = 10;
    items.forEach(item => {
      let a = item.querySelector('a');
      contents.push({
        title: a.innerText,
        details: a.dataset.c,
        link: a.href
      })
      item.remove();
    })

    function insertStr(soure, start, count) {
      let newStr = soure.substr(start, count);
      return soure.slice(0, start) + '<em>' + newStr + '</em>' + soure.slice(start + count);
    }

    pageUl.addEventListener('click', function(event) {
      let target = event.target;
      if (target.__proto__ === HTMLSpanElement.prototype) {
        appendResults(parseInt(target.dataset.i));
      }
    })

    function appendResults(index) {
      let htmlResult = '';
      let start = index || 0;
      let end = Math.min(start + pageSize, finds.length);
      for (let i = start; i < end; i++) {
        const current = finds[i];
        let html = current.title;
        let sum = 0;
        let positions = current.positions;
        positions.forEach(position => {
          html = insertStr(html, position.start + sum, position.count);
          sum += 9;
        })
        htmlResult += `<div class="item"><a class="result-title" href="${current.link}">${html}</a></div>`;
      }
      result.innerHTML = htmlResult;
      pageUl.innerHTML = '';
      let count = finds.length / pageSize;
      let lis = '';
      if (start !== 0) {
        lis += `<span class="fa fa-angle-left" data-i='${start - 1}'></span>`;
      }
      for (let i = 0; i < count; i++) {
        lis += `<span class='${i === start?'current':''}' data-i='${i}'>${i+1}</span>`;     
      }
      if (start+1 < count) {
        lis += `<span class="fa fa-angle-right" data-i='${start+1}'></span>`;  
      }
      pageUl.innerHTML = lis;
    }

    function search(delay) {
      let timer = null
      return function () {
        clearTimeout(timer)
        timer = setTimeout(() => {
          let start = Date.now();
          let segments = searchBox.value.split(' ').filter(c => c != '');
          if (segments.length <= 0) {
            return;
          }
          finds = [];
          let htmlResult = '';
          contents.forEach(content => {
            let title = content.title;
            let positions = [];
            let find = false;
            segments.forEach((segment) => {
              if (content.title.includes(segment)) {
                find = true;
                positions.push({
                  start: content.title.indexOf(segment),
                  count: segment.length
                })
              } else if (content.details.includes(segment)) {
                find = true;
              }
            });
            if (find) {
              finds.push({
                title: content.title,
                link: content.link,
                positions
              });
            }
          })
          appendResults(0);
          statCount.textContent = finds.length;
          statTimes.textContent = Date.now() - start;
        }, delay)
      }
    }
    searchBox.addEventListener('input', search(200));
  }()
</script>

<input hidden id="copy" />
<script>
  !function () {
    let times = document.querySelectorAll('.publish-time');
    for (let i = 0; i < times.length; i++) {
      let date = times[i].dataset.t;
      let time = Math.floor((new Date().getTime() - new Date(date).getTime()) / 1000);
      if (time < 60) {
        str = time + '秒之前';
      } else if (time < 3600) {
        str = Math.floor(time / 60) + '分钟之前';
      } else if (time >= 3600 && time < 86400) {
        str = Math.floor(time / 3600) + '小时之前';
      } else if (time >= 86400 && time < 259200) {
        str = Math.floor(time / 86400) + '天之前';
      } else {
        str = times[i].textContent;
      }
      times[i].textContent = str;
    }
  }();
</script>

<script>
  let language = '';
  if (language !== '') {
    let map = new Map();
    if (language === 'en') {
      map.set('search', 'Search');
      map.set('category', 'Categories');
      map.set('article', 'Articles');
      map.set('tag', 'Tags');
      map.set('top', 'Top');
      map.set('publish', 'published');
      map.set('minute', ' minutes');
      map.set('read-more', 'Read More');
      map.set('view', 'View');
      map.set('words', ' words');
      map.set('category-in', 'category in');
      map.set('preview', 'Meta');
      map.set('index', 'Toc');
      map.set('no-archives', "You haven't created yet");
      map.set('archives', " articles in total");
      map.set('cloud-tags', " tags in total");
      map.set('copyright', "Copyright: ");
      map.set('author', "Author: ");
      map.set('link', "Link: ");
      map.set('leave-message', "Leave a message");
      map.set('format', "Links Format");
      map.set('site-name', "Name: ");
      map.set('site-link', "Link: ");
      map.set('site-desc', "Desc: ");
      map.set('stat', " related results, taking ");
      map.set('stat-time', " ms");
      map.set('site-img', "Image: ");
    }

    if (map.size > 0) {
      let lanElems = document.querySelectorAll('.language');
      lanElems.forEach(elem => {
        let lan = elem.dataset.lan, text = map.get(lan);
        if (elem.__proto__ === HTMLInputElement.prototype) {
          elem.placeholder = text
        } else {
          if (elem.dataset.count) {
            text = elem.dataset.count + text;
          }
          elem.textContent = text;
        }
      })
    }
  }
  //拿来主义(真香)^_^，Clipboard 实现摘自掘金 https://juejin.im/post/5aefeb6e6fb9a07aa43c20af
  window.Clipboard = (function (window, document, navigator) {
    var textArea,
      copy;

    // 判断是不是ios端
    function isOS() {
      return navigator.userAgent.match(/ipad|iphone/i);
    }
    //创建文本元素
    function createTextArea(text) {
      textArea = document.createElement('textArea');
      textArea.value = text;
      textArea.style.width = 0;
      textArea.style.height = 0;
      textArea.clientHeight = 0;
      textArea.clientWidth = 0;
      document.body.appendChild(textArea);
    }
    //选择内容
    function selectText() {
      var range,
        selection;

      if (isOS()) {
        range = document.createRange();
        range.selectNodeContents(textArea);
        selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
        textArea.setSelectionRange(0, 999999);
      } else {
        textArea.select();
      }
    }

    //复制到剪贴板
    function copyToClipboard() {
      try {
        document.execCommand("Copy")
      } catch (err) {
        alert("复制错误！请手动复制！")
      }
      document.body.removeChild(textArea);
    }

    copy = function (text) {
      createTextArea(text);
      selectText();
      copyToClipboard();
    };

    return {
      copy: copy
    };
  })(window, document, navigator);

  function copyCode(e) {
    if (e.srcElement.tagName === 'SPAN' && e.srcElement.classList.contains('copy-code')) {
      let code = e.currentTarget.querySelector('code');
      var text = code.innerText;
      if (e.srcElement.textContent === '复制成功') {
        return;
      }
      e.srcElement.textContent = '复制成功';
      (function (elem) {
        setTimeout(() => {
          if (elem.textContent === '复制成功') {
            elem.textContent = '复制代码'
          }
        }, 1000);
      })(e.srcElement)
      Clipboard.copy(text);
    }
  }

  let pres = document.querySelectorAll('pre');
  pres.forEach(pre => {
    let code = pre.querySelector('code');
    let copyElem = document.createElement('span');
    copyElem.classList.add('copy-code');
    copyElem.textContent = '复制代码';
    pre.appendChild(copyElem);
    pre.onclick = copyCode
  })

</script>
<script src="/media/js/motion.js"></script>

<script src="https://cdn.jsdelivr.net/gh/cferdinandi/smooth-scroll/dist/smooth-scroll.polyfills.min.js"></script>
<script>
  var scroll = new SmoothScroll('a[href*="#"]', {
    speed: 200
  });
</script>





<script src="https://cdn.jsdelivr.net/gh/lete114/CDN/Sum/sakura.js"></script>


</html>